18
18
19
19
import time
20
20
from argparse import ArgumentParser
21
+ from concurrent .futures import Future
21
22
from typing import Any
22
23
23
24
from pymavswarm import MavSwarm
24
- from pymavswarm .types import AgentID
25
25
26
26
27
27
def parse_args () -> Any :
@@ -36,48 +36,96 @@ def parse_args() -> Any:
36
36
"port" , type = str , help = "port to establish a MAVLink connection over"
37
37
)
38
38
parser .add_argument ("baud" , type = int , help = "baudrate to establish a connection at" )
39
+ parser .add_argument ("config" , type = str , help = "Pre-planned positions to load" )
39
40
parser .add_argument (
40
41
"--takeoff_alt" , type = float , default = 3.0 , help = "altitude to takeoff to [m]"
41
42
)
43
+ parser .add_argument (
44
+ "--ground_speed" ,
45
+ type = float ,
46
+ default = 3.0 ,
47
+ help = "ground speed that the agents should fly at when flying to the target "
48
+ "location" ,
49
+ )
42
50
return parser .parse_args ()
43
51
44
52
53
+ def print_message_response_cb (future : Future ) -> None :
54
+ """
55
+ Print the result of the future.
56
+
57
+ :param future: message execution future
58
+ :type future: Future
59
+ """
60
+ responses = future .result ()
61
+
62
+ if isinstance (responses , list ):
63
+ for response in responses :
64
+ print (
65
+ f"Result of { response .message_type } message sent to "
66
+ f"({ response .target_agent_id } ): { response .code } "
67
+ )
68
+ else :
69
+ print (
70
+ f"Result of { responses .message_type } message sent to "
71
+ f"({ responses .target_agent_id } ): { responses .code } "
72
+ )
73
+
74
+ return
75
+
76
+
45
77
def main () -> None :
46
78
"""Demonstrate how to command agents to go to a location."""
47
79
# Parse the script arguments
48
80
args = parse_args ()
49
81
50
82
# Create a new MavSwarm instance
51
- mavswarm = MavSwarm ()
83
+ mavswarm = MavSwarm (log_to_file = True )
52
84
53
85
# Attempt to create a new MAVLink connection
54
86
if not mavswarm .connect (args .port , args .baud ):
55
87
return
56
88
57
- # Wait for the swarm to auto-register new agents
58
- while not list (filter (lambda agent_id : agent_id [1 ] == 1 , mavswarm .agent_ids )):
59
- print ("Waiting for the system to recognize agents in the network..." )
89
+ # Get the target agents specified in the config file
90
+ target_agents = list (mavswarm .parse_yaml_mission (args .config )[0 ].keys ())
91
+
92
+ # Wait for the swarm to register all target agents
93
+ while not all (agent_id in mavswarm .agent_ids for agent_id in target_agents ):
94
+ print ("Waiting for the system to recognize all target agents..." )
60
95
time .sleep (0.5 )
61
96
62
97
# Set each agent to guided mode before attempting a takeoff sequence
63
- future = mavswarm .set_mode ("GUIDED" , retry = True )
98
+ future = mavswarm .set_mode (
99
+ "GUIDED" , agent_ids = target_agents , retry = True , verify_state = True
100
+ )
101
+ future .add_done_callback (print_message_response_cb )
64
102
65
103
while not future .done ():
66
104
pass
67
105
68
106
responses = future .result ()
69
107
70
- for response in responses :
71
- if not response .result :
108
+ # Exit if all agents didn't successfully switch into GUIDED mode
109
+ if isinstance (responses , list ):
110
+ for response in responses :
111
+ if not response .result :
112
+ print (
113
+ "Failed to set the flight mode of agent "
114
+ f"{ response .target_agent_id } to GUIDED prior to the takeoff "
115
+ "sequence. Exiting."
116
+ )
117
+ return
118
+ else :
119
+ if not responses .result :
72
120
print (
73
- "Failed to set the flight mode of all agents to GUIDED prior to the "
74
- "takeoff sequence. Exiting."
121
+ "Failed to set the flight mode of agent {responses.target_agent_id} to "
122
+ "GUIDED prior to the takeoff sequence. Exiting."
75
123
)
76
124
return
77
125
78
126
# Perform takeoff with all agents in the swarm; retry on message failure
79
127
responses = mavswarm .takeoff_sequence (
80
- args .takeoff_alt , verify_state = True , retry = True
128
+ args .takeoff_alt , agent_ids = target_agents , verify_state = True , retry = True
81
129
)
82
130
83
131
if isinstance (responses , list ):
@@ -92,64 +140,40 @@ def main() -> None:
92
140
f"({ response .target_agent_id } ): { responses .code } "
93
141
)
94
142
95
- target_locations : dict [AgentID , tuple [float , float , float ]] = {}
96
-
97
- # Get the target positions
98
- for agent_id in mavswarm .agent_ids :
99
- lat = float (input (f"Enter the target latitude for agent { agent_id } : " ))
100
- lon = float (input (f"Enter the target longitude for agent { agent_id } : " ))
101
- alt = float (input (f"Enter the target altitude for agent { agent_id } : " ))
102
-
103
- target_locations [agent_id ] = (lat , lon , alt )
104
-
105
- print (f"Target locations specified: { target_locations } " )
106
-
107
143
# Wait for the user to indicate that the agents should fly to their waypoints
108
144
input ("Press any key to command the agents to fly to their waypoints" )
109
145
110
- for agent_id in target_locations .keys ():
111
- future = mavswarm .goto (
112
- target_locations [agent_id ][0 ],
113
- target_locations [agent_id ][1 ],
114
- target_locations [agent_id ][2 ],
115
- agent_ids = agent_id ,
116
- retry = True ,
117
- )
118
-
119
- while not future .done ():
120
- pass
146
+ # Command the agent to the target location
147
+ # We don't need to specify the target agents because these are captured from the
148
+ # config file
149
+ future = mavswarm .goto (config_file = args .config , retry = True )
150
+ future .add_done_callback (print_message_response_cb )
121
151
122
- response = future .result ()
152
+ while not future .done ():
153
+ pass
123
154
124
- print (
125
- f"Result of { response .message_type } message sent to "
126
- f"({ response .target_agent_id } ): { response .code } "
127
- )
155
+ # Set the groundspeed
156
+ future = mavswarm .set_groundspeed (
157
+ args .ground_speed , agent_ids = target_agents , retry = True
158
+ )
159
+ future .add_done_callback (print_message_response_cb )
128
160
129
- if not response .result :
130
- print (
131
- f"Failed to command agent { agent_id } to location "
132
- f"{ target_locations [agent_id ]} "
133
- )
161
+ while not future .done ():
162
+ pass
134
163
135
164
# Wait for user input
136
165
input ("Press any key to command the agents to land" )
137
166
138
167
# Attempt to land the agents
139
- future = mavswarm .set_mode ("LAND" , retry = True , verify_state = True )
168
+ future = mavswarm .set_mode (
169
+ "LAND" , agent_ids = target_agents , retry = True , verify_state = True
170
+ )
171
+ future .add_done_callback (print_message_response_cb )
140
172
141
173
# Wait for the land command to complete
142
174
while not future .done ():
143
175
pass
144
176
145
- landing_responses = future .result ()
146
-
147
- for response in landing_responses :
148
- print (
149
- f"Result of { response .message_type } message sent to "
150
- f"({ response .target_agent_id } ): { response .code } "
151
- )
152
-
153
177
# Disconnect from the swarm
154
178
mavswarm .disconnect ()
155
179
0 commit comments