Coverage for D:\Ralf Gerlich\git\modypy\modypy\blocks\aerodyn.py: 0%

# Coverage for D:\Ralf Gerlich\git\modypy\modypy\blocks\aerodyn.py : 0%

## 52 statements

Hot-keys on this page

r m x p toggle line displays

j k next/prev highlighted chunk

0 (zero) top of page

1 (one) first highlighted chunk

1"""

2 A collection of blocks useful for aerodynamics.

3"""

4 import math

5

6 import numpy as np

7 from modypy.model import Block, Port, signal_method

8

9

10 class Propeller(Block):

11 """A block representing a propeller.

12

13 The block has two inputs:

14

15 ``speed_rps``

16 The speed of the propeller in revolutions per second

17 ``density``

18 The density of the air

19

20 It provides three outputs:

21

22 ``thrust``

23 The total scalar thrust generated by the propeller

24 ``torque``

25 The total torque required by the propeller

26 ``power``

27 The total power required by the propeller

28

29 The magnitudes of thrust, torque and power are determined by the following

30 formulae::

31

32 F = ct(n)*rho*D^5*n^2

33 tau = cp(n)/(2*pi)*rho*D^5*n^2

34 P = cp(n)*rho*D^5*n^3

35

36 Here,

37 - ``ct(n)`` is the thrust coefficient at speed ``n``,

38 - ``cp(n)`` is the power coefficient at speed ``n``, and

39 - ``D`` is the diameter.

40 """

41

42 def __init__(self,

43 parent,

44 thrust_coefficient,

45 power_coefficient,

46 diameter):

47 Block.__init__(self, parent)

48 if not callable(thrust_coefficient):

49 thrust_coeff_value = thrust_coefficient

50 thrust_coefficient = (lambda n: thrust_coeff_value)

51 if not callable(power_coefficient):

52 power_coeff_value = power_coefficient

53 power_coefficient = (lambda n: power_coeff_value)

54

55 self.thrust_coefficient = thrust_coefficient

56 self.power_coefficient = power_coefficient

57 self.diameter = diameter

58

59 self.speed_rps = Port()

60 self.density = Port()

61

62 @signal_method

63 def thrust(self, data):

64 """Function used to calculate the ``thrust`` output

65 """

66 speed_rps = self.speed_rps(data)

67 density = self.density(data)

68 return self.thrust_coefficient(speed_rps) \

69 * density * self.diameter ** 4 * speed_rps ** 2

70

71 @signal_method

72 def torque(self, data):

73 """Function used to calculate the ``torque`` output

74 """

75 speed_rps = self.speed_rps(data)

76 density = self.density(data)

77 return self.power_coefficient(speed_rps) / (2 * math.pi) * \

78 density * self.diameter ** 5 * speed_rps ** 2

79

80 @signal_method

81 def power(self, data):

82 """Function used to calculate the ``power`` output

83 """

84 speed_rps = self.speed_rps(data)

85 density = self.density(data)

86 return self.power_coefficient(speed_rps) * \

87 density * self.diameter ** 5 * np.abs(speed_rps ** 3)

88

89

90 class Thruster(Block):

91 """A block representing a thruster.

92

93 A thruster converts scalar thrust and torque to thrust and torque vectors.

94 The thrust is considered to work in a (constant) thrust direction,

95 determined by the thrust axis.

96

97 Torque is combined thrust along the thrust axis and torque due to the thrust

98 working at the end of a (constant) arm relative to the center of gravity

99 (CoG) of a rigid body.

100

101 The block has two inputs:

102 - The scalar thrust in the direction of the thrust axis, and

103 - the scalar torque along the thrust axis.

104

105 The block has six outputs:

106 - The thrust vector (3 components), and

107 - the torque vector (3 components).

108

109 It is configured by

110 - the thrust axis (vector X,Y,Z),

111 - the thrust arm (vector X,Y,Z), and

112 - the turning direction (scalar: +1 or -1).

113

114 The right-hand rule applied to the thrust axis gives the positive direction

115 of the thruster. Torque acts in the *opposite* direction, i.e. if the

116 thruster turns clockwise, torque acts counter-clockwise.

117 """

118

119 def __init__(self,

120 parent,

121 vector,

122 arm,

123 direction=1):

124 Block.__init__(self, parent)

125 self.vector = vector

126 self.arm = arm

127 self.direction = direction

128

129 self.scalar_thrust = Port()

130 self.scalar_torque = Port()

131

132 @signal_method(shape=3)

133 def thrust_vector(self, data):

134 """Function used to calculate the ``thrust_vector`` output

135 """

136 thrust = self.scalar_thrust(data)

137 thrust_vector = self.vector * thrust

138 return thrust_vector

139

140 @signal_method(shape=3)

141 def torque_vector(self, data):

142 """Function used to calculate the ``torque_vector`` output

143 """

144 thrust = self.scalar_thrust(data)

145 torque = self.scalar_torque(data)

146

147 thrust_vector = self.vector * thrust

148 torque_vector = self.direction * self.vector * torque + \

149 np.cross(self.arm, thrust_vector)

150

151 return torque_vector