-
Notifications
You must be signed in to change notification settings - Fork 4
/
trajectory-healthy.py
148 lines (115 loc) · 5.03 KB
/
trajectory-healthy.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
"""
Description of what this file does.
"""
import os
import sys
cur_path=os.path.abspath(os.path.dirname(__file__))
sys.path.insert(0, cur_path+"/..")
from src.utility.logger import *
from dronekit import connect, mavutil, VehicleMode, LocationGlobalRelative
import time
logging.debug('Beginning of code...')
class Autopilot:
""" A Dronekit autopilot connection manager. """
def __init__(self, connection_string, *args, **kwargs):
logging.debug('connecting to Drone (or SITL/HITL) on: %s', connection_string)
self.master = connect(connection_string, wait_ready=True)
# Add a heartbeat listener
def heartbeat_listener(_self, name, msg):
self.last_heartbeat = msg
self.heart = heartbeat_listener
logging.info('Drone connection successful')
def __enter__(self):
''' Send regular heartbeats while using in a context manager. '''
logging.info('__enter__ -> reviving heart (if required)')
# Listen to the heartbeat
self.master.add_message_listener('HEARTBEAT', self.heart)
return self
def __exit__(self, *args):
''' Automatically disarm and stop heartbeats on error/context-close. '''
logging.info('__exit__ -> disarming, stopping heart and closing connection')
# TODO: add reset parameters procedure. Can be based on flag?
# Disarm if not disarmed
if self.master.armed:
self.master.armed = False
# Kill heartbeat
self.master.remove_message_listener('HEARTBEAT', self.heart)
# Close Drone connection
logging.info('disconnect -> closing Drone connection')
self.master.close()
if __name__ == '__main__':
# Set up option parsing to get connection string
import argparse
parser = argparse.ArgumentParser(description='Description of what this file does.')
parser.add_argument('--connect',
help="Vehicle connection target string. If not specified, SITL automatically started and used.")
args = parser.parse_args()
connection_string = args.connect
if not connection_string:
connection_string = '127.0.0.1:14551'
if not connection_string:
logging.critical("No connection string specified, exiting code.")
exit()
with Autopilot(connection_string) as drone:
logging.debug("Ready: %s", drone)
def set_servo(motor_num, pwm_value):
pwm_value_int = int(pwm_value)
msg = drone.master.message_factory.command_long_encode(
0, 0,
mavutil.mavlink.MAV_CMD_DO_SET_SERVO,
0,
motor_num,
pwm_value_int,
0,0,0,0,0
)
drone.master.send_mavlink(msg)
def set_motor_mode(motor_num, set_reset):
# get servo function - what this motor does
logging.debug("GOT PARAM: %s", drone.master.parameters[f'SERVO{motor_num}_FUNCTION'])
time.sleep(1)
# set servo function - change to 1 for RCPassThru
drone.master.parameters[f'SERVO{motor_num}_FUNCTION'] = set_reset
time.sleep(1)
set_motor_mode(1, 33)
set_motor_mode(2, 34)
set_motor_mode(3, 35)
set_motor_mode(4, 36)
set_motor_mode(5, 37)
set_motor_mode(6, 38)
logging.debug("Basic pre-arm checks")
# Don't try to arm until autopilot is ready
while not drone.master.is_armable:
logging.debug(" Waiting for vehicle to initialise...")
time.sleep(1)
print("Arming motors")
# Copter should arm in GUIDED mode
drone.master.mode = VehicleMode("GUIDED")
drone.master.armed = True
# Confirm vehicle armed before attempting to take off
while not drone.master.armed:
print(" Waiting for arming...")
time.sleep(1)
print("Taking off!")
drone.master.simple_takeoff(10) # Take off to target altitude
# Wait until the vehicle reaches a safe height before processing the goto
# (otherwise the command after Vehicle.simple_takeoff will execute
# immediately).
while True:
print(" Altitude: ", drone.master.location.global_relative_frame.alt)
# Break and return from function just below target altitude.
if drone.master.location.global_relative_frame.alt >= 10 * 0.95:
print("Reached target altitude")
break
time.sleep(1)
logging.debug("Set default/target airspeed to 3")
drone.master.airspeed = 3
logging.debug("Going towards first point for 30 seconds ...")
point1 = LocationGlobalRelative(-35.361354, 149.165218, 20)
drone.master.simple_goto(point1)
# sleep so we can see the change in map
time.sleep(15)
logging.debug("Last Heartbeat: %s", drone.last_heartbeat)
print("Setting LAND mode...")
drone.master.mode = VehicleMode("LAND")
# sleep so we can see the change in map
time.sleep(5)