|
1 | 1 | #!/usr/bin/env python
|
2 |
| -# -*- coding: utf-8 -*- |
3 | 2 |
|
4 | 3 | """
|
5 | 4 |
|
@@ -85,40 +84,57 @@ def arm_and_takeoff_nogps(aTargetAltitude):
|
85 | 84 | set_attitude(thrust = thrust)
|
86 | 85 | time.sleep(0.2)
|
87 | 86 |
|
88 |
| - |
89 |
| -def set_attitude(roll_angle = 0.0, pitch_angle = 0.0, yaw_rate = 0.0, thrust = 0.5, duration = 0): |
90 |
| - """ |
91 |
| - Note that from AC3.3 the message should be re-sent every second (after about 3 seconds |
92 |
| - with no message the velocity will drop back to zero). In AC3.2.1 and earlier the specified |
93 |
| - velocity persists until it is canceled. The code below should work on either version |
94 |
| - (sending the message multiple times does not cause problems). |
95 |
| - """ |
96 |
| - |
| 87 | +def send_attitude_target(roll_angle = 0.0, pitch_angle = 0.0, |
| 88 | + yaw_angle = None, yaw_rate = 0.0, use_yaw_rate = False, |
| 89 | + thrust = 0.5): |
97 | 90 | """
|
98 |
| - The roll and pitch rate cannot be controllbed with rate in radian in AC3.4.4 or earlier, |
99 |
| - so you must use quaternion to control the pitch and roll for those vehicles. |
| 91 | + use_yaw_rate: the yaw can be controlled using yaw_angle OR yaw_rate. |
| 92 | + When one is used, the other is ignored by Ardupilot. |
| 93 | + thrust: 0 <= thrust <= 1, as a fraction of maximum vertical thrust. |
| 94 | + Note that as of Copter 3.5, thrust = 0.5 triggers a special case in |
| 95 | + the code for maintaining current altitude. |
100 | 96 | """
|
101 |
| - |
| 97 | + if not use_yaw_rate and yaw_angle is None: |
| 98 | + yaw_angle = vehicle.attitude.yaw |
102 | 99 | # Thrust > 0.5: Ascend
|
103 | 100 | # Thrust == 0.5: Hold the altitude
|
104 | 101 | # Thrust < 0.5: Descend
|
105 | 102 | msg = vehicle.message_factory.set_attitude_target_encode(
|
106 | 103 | 0, # time_boot_ms
|
107 | 104 | 1, # Target system
|
108 | 105 | 1, # Target component
|
109 |
| - 0b00000000, # Type mask: bit 1 is LSB |
110 |
| - to_quaternion(roll_angle, pitch_angle), # Quaternion |
| 106 | + 0b00000000 if use_yaw_rate else 0b00000100, |
| 107 | + to_quaternion(roll_angle, pitch_angle, yaw_angle), # Quaternion |
111 | 108 | 0, # Body roll rate in radian
|
112 | 109 | 0, # Body pitch rate in radian
|
113 |
| - math.radians(yaw_rate), # Body yaw rate in radian |
| 110 | + math.radians(yaw_rate), # Body yaw rate in radian/second |
114 | 111 | thrust # Thrust
|
115 | 112 | )
|
116 | 113 | vehicle.send_mavlink(msg)
|
117 | 114 |
|
| 115 | +def set_attitude(roll_angle = 0.0, pitch_angle = 0.0, |
| 116 | + yaw_angle = None, yaw_rate = 0.0, use_yaw_rate = False, |
| 117 | + thrust = 0.5, duration = 0): |
| 118 | + """ |
| 119 | + Note that from AC3.3 the message should be re-sent more often than every |
| 120 | + second, as an ATTITUDE_TARGET order has a timeout of 1s. |
| 121 | + In AC3.2.1 and earlier the specified attitude persists until it is canceled. |
| 122 | + The code below should work on either version. |
| 123 | + Sending the message multiple times is the recommended way. |
| 124 | + """ |
| 125 | + send_attitude_target(roll_angle, pitch_angle, |
| 126 | + yaw_angle, yaw_rate, False, |
| 127 | + thrust) |
118 | 128 | start = time.time()
|
119 | 129 | while time.time() - start < duration:
|
120 |
| - vehicle.send_mavlink(msg) |
| 130 | + send_attitude_target(roll_angle, pitch_angle, |
| 131 | + yaw_angle, yaw_rate, False, |
| 132 | + thrust) |
121 | 133 | time.sleep(0.1)
|
| 134 | + # Reset attitude, or it will persist for 1s more due to the timeout |
| 135 | + send_attitude_target(0, 0, |
| 136 | + 0, 0, True, |
| 137 | + thrust) |
122 | 138 |
|
123 | 139 | def to_quaternion(roll = 0.0, pitch = 0.0, yaw = 0.0):
|
124 | 140 | """
|
|
0 commit comments