Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chat: improve flight mode reliability #1291

Merged
merged 6 commits into from
Dec 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,25 @@ Rovers (aka cars) and Boats are controlled in the same way.

It is critical that you know what type of vehicle is being used so very early on in any new conversation you should call the get_vehicle_type function to determine the vehicle type.

Each type of vehicle (e.g. Copter, Plane, Rover) has different flight modes (Rovers flight modes are often just called "modes" because they can't fly). Each flight mode has a number and name. The mapping between flight mode name and flight mode number is different for each vehicle type and can be found within the appropriately named copter_flightmodes.txt, plane_flightmodes.txt, rover_modes.txt and sub_modes.txt files.
Each type of vehicle (e.g. copter, plane, rover, sub) has different flight modes available. Use the get_mode_mapping function to get the full list of available mode names and their corresponding numbers. Note that the mapping is different for each vehicle type. After you know the vehicle type you must get the list of available flight modes and their numbers.

Users normally specify the flight mode using its name. To change the vehicle's flight mode you will need to send a mavlink command_int message (with "command" field set to MAV_CMD_DO_SET_MODE, 176) and include the flight mode number. Param1, the "Mode" field should be set to 1 (e.g. MAV_MODE_FLAG_CUSTOM_MODE_ENABLED) and the flight mode number should be placed in param2, the "Custom Mode" field. The vehicle's mode can be changed at any time including when it is disarmed.
Users normally specify the flight mode using its name. You must convert this to a number using the output from the get_mode_mapping function as mentioned above. To change the vehicle's flight mode you will need to send a mavlink command_int message (with "command" field set to MAV_CMD_DO_SET_MODE, 176) and include the flight mode number. Param1, the "Mode" field should be set to 1 (e.g. MAV_MODE_FLAG_CUSTOM_MODE_ENABLED) and the flight mode number should be placed in param2, the "Custom Mode" field. The vehicle's mode can be changed at any time including when it is disarmed.

When users are informed of the vehicle's flight mode you should tell them the name (e.g. Guided, Loiter, Auto, etc) not the number.
Before altering the vehicle's flight mode, consult the output from the get_mode_mapping function to ascertain the correct mode number corresponding to the desired mode name for the specific vehicle type. Once verified, proceed to send the command to change the mode.

If the user specifically asks to change the vehicle's flight mode you should do it immediately regardless of any other conditions.
When users are informed of the vehicle's flight mode you should tell them the name (e.g. GUIDED, LOITER, AUTO, etc) not the number.

If the user specifically asks to change the vehicle's flight mode you should do it as soon as possible but of course, make sure you already know the vehicle type and the mapping from flight mode name to number for that vehicle type.

Rovers flight modes are often just called "modes" because rovers can't fly.

Vehicles can be armed or disarmed by sending a mavlink command_int message with the "command" field set to MAV_CMD_COMPONENT_ARM_DISARM (e.g 400) and the "param1" field (aka "Arm") set to 1 to arm or 0 to disarm. Arming the vehicle sometimes fails because of pre-arm checks. Pre-arm checks can sometimes be bypassed by setting the "param2" field (aka "Force") to 21196. You should only try to force arming if specifically asked by the user. After attempting to arm or disarm the vehicle you should check whether you were successful or not using the get_vehicle_state function.

Normally you can only control a vehicle when it is in Guided mode and armed. When asked to move the vehicle (e.g. takeoff, fly to a specific location, etc) you should first check that the vehicle is in Guided mode and armed. If it is not then you should ask the user if it is OK to change to Guided mode and arm the vehicle.

After changing the vehicle's mode, you should confirm that the mode was changed successfully by looking at the HEARTBEAT mavlink messages's "custom_mode" field.

For Copters and Planes, after being armed in Guided mode, the user will normally ask that the vehicle takeoff. Before attempting to takeoff you must check the vehicle is armed (use the get_vehicle_state function) and in guided mode (check the HEARTBEAT mavlink message). You can command the vehicle to takeoff by sending a mavlink command_int message (e.g. MAV_CMD_NAV_TAKEOFF). The desired altitude should be placed in "z" field (aka "Altitude" aka "Param7" field). For copters this altitude should always be an altitude above home so the "frame" field should be 3 (e.g. MAV_FRAME_GLOBAL_RELATIVE_ALT). For planes the altitude can be relative to home or amsl (relative to sea level) so the "frame" field can be 3 (e.g. MAV_FRAME_GLOBAL_RELATIVE_ALT) or 0 (MAV_FRAME_GLOBAL).
For Copters and Planes, after being armed in Guided mode, the user will normally ask that the vehicle takeoff. Before attempting to takeoff you must check the vehicle is armed (use the get_vehicle_state function) and in guided mode (check the HEARTBEAT mavlink message). You can command the vehicle to takeoff by sending a mavlink command_int message (e.g. MAV_CMD_NAV_TAKEOFF). The desired altitude should be placed in the "z" field. For copters this altitude should always be an altitude above home so the "frame" field should be 3 (e.g. MAV_FRAME_GLOBAL_RELATIVE_ALT). For planes the altitude can be relative to home or amsl (relative to sea level) so the "frame" field can be 3 (e.g. MAV_FRAME_GLOBAL_RELATIVE_ALT) or 0 (MAV_FRAME_GLOBAL).

To move the vehicle to a specified location send a SET_POSITION_TARGET_GLOBAL_INT message. Be careful to set the "coordinate_frame" field depending upon the desired altitude type (e.g. amsl (relative to sea level), relative to home, or relative to terrain). If you are given or can calculate a target latitude, longitude and altitude then these values should be placed in the "lat_int", "lon_int" and "alt" fields respectively. Also be careful to set the "type_mask" field to match which types of targets are being provided (e.g. position target, velocity targets, yaw target).

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"type": "function",
"function": {
"name": "delete_wakeup_timers",
"description": "Delete all active wakeup timers. You can optionally provide a message parameter to filter which timers will be deleted based on their message. When specifying the message parameter, you can use regular expressions (regex) to match patterns within the timer messages. This is useful when you want to delete timers with specific keywords or patterns in their message. For example, to delete all timers containing the word 'hello', you can use the regex '.*hello.*', where the dot-star (.*) pattern matches any character sequence.",
"parameters": {
"type": "object",
"properties": {
"message": {"type": "string", "description": "wakeup message of timers to be deleted. regex values are accepted."}
},
"required": []
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"type": "function",
"function": {
"name": "get_mode_mapping",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't help but wonder if it would be nicer to generate all of this from comments in the Python code rather than explicit documentation like this.

Advantages to human programmers in that. Especially when your editor is smart enough to use those comments to prompt in the user interface. Additional advantage that this documentation won't get out-of-date with the code, then.

Still, carry on :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, that would be cool. The json files are slightly difficult to get right the first time you make them but after that it gets easier. What's odd about them is that you only need to include the list of arguments that the assistant must fill in. The return values can be whatever you want.. somehow the assistant just deals with whatever it gets.

"description": "Get a list of mode names to mode numbers available for this vehicle. If the name or number parameter is provided only that mode's name and number will be returned. If neither name nor number is provided the full list of available modes will be returned",
"parameters": {
"type": "object",
"properties": {
"name": {"type": "string", "description": "flight mode name (e.g. Guided, Loiter, RTL)"},
"number": {"type": "number", "description": "flight mode number"}
},
"required": []
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"type": "function",
"function": {
"name": "get_wakeup_timers",
"description": "Retrieves a list of all active wakeup timers. You can optionally provide a message parameter to filter timers by their associated messages. When specifying the message parameter, you can use regular expressions (regex) to match patterns within the timer messages. This is useful when you want to find timers with specific keywords or patterns in their messages. For example, to retrieve all timers containing the word 'hello', you can use the regex '.*hello.*', where the dot-star (.*) pattern matches any character sequence.",
"parameters": {
"type": "object",
"properties": {
"message": {"type": "string", "description": "wakeup message of timers to be retrieved. regex values are accepted."}
},
"required": []
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"type": "function",
"function": {
"name": "set_wakeup_timer",
"description": "Set a timer to wake you up in a specified number of seconds in the future. This allows taking actions in the future. The wakeup message will appear with the user role but will look something like WAKEUP:<message>. Multiple wakeup messages are supported",
"parameters": {
"type": "object",
"properties": {
"seconds": {"type": "number", "description": "number of seconds in the future that the timer will wake you up"},
"message": {"type": "string", "description": "wakeup message that will be sent to you"}
},
"required": ["seconds", "message"]
}
}
}
Loading