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

AP_DDS: External Control enable #28429

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

tizianofiorenzani
Copy link
Contributor

@tizianofiorenzani tizianofiorenzani commented Oct 18, 2024

User Story

As an operator, I want to be able to completely cut off any external control from the DDS interface. This functionality is especially helpful during debugging tests, when a quick reaction is of utmost importance.
I would like to be able to assign a switch to Enable/Disable external control, as well as the ability for a script or an external GCS to trigger External Control.

What Changed

  • AP_ExternalControl has now the ability to set and retrieve its status.
  • AP_DDS prevents any Subscription or Service to affect the vehicle: Subscriptions callbacks are simply returned, while service requests reply with false.
  • RC_Channel has been given a new functionality DDS_EXTERNAL_CONTROL = 181 which allows a channel to enable External control when HIGH.

Test

  • For now I left the /ap/joy subscription always active, so it's easy to emulate an RC input.
  • I assigned RC6_OPTION = 181
  • Start the SITL
  • Set the RC switch to High ros2 topic pub /ap/joy sensor_msgs/msg/Joy "{axes: [0.0, 0.0, .nan, .nan, .nan, -1]}"
  • Try to Arm the vehicle with ros2 service call /ap/arm_motors ardupilot_msgs/srv/ArmMotors "arm: true"
  • Arming command is rejected!

image

  • Set the RC switch to High ros2 topic pub /ap/joy sensor_msgs/msg/Joy "{axes: [0.0, 0.0, .nan, .nan, .nan, 1]}"
  • Try to Arm the vehicle with ros2 service call /ap/arm_motors ardupilot_msgs/srv/ArmMotors "arm: true"
  • Vehicle is Armed

image

@@ -636,6 +637,13 @@ void AP_DDS_Client::on_topic(uxrSession* uxr_session, uxrObjectId object_id, uin
(void) request_id;
(void) stream_id;
(void) length;
auto *external_control = AP::externalcontrol();
// TODO: Replace this line before merging. I leave the Joystick control always enable to test the RC functionality.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Replace this before merging.

@tizianofiorenzani
Copy link
Contributor Author

@Ryanf55 what is the best way to make it testable?

@Ryanf55
Copy link
Collaborator

Ryanf55 commented Oct 19, 2024

@Ryanf55 what is the best way to make it testable?

I'd do something like a mock flyaway recovery.

  1. Take off
  2. Command 100% throttle on AP_DDS joystick topic
  3. Wait till drone reaches 400'
  4. Disable external control using mavlink
  5. Check it never hits 500'

Copy link
Collaborator

@Ryanf55 Ryanf55 left a comment

Choose a reason for hiding this comment

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

I've replicated your behavior, looks great! I think this is a nice clean way for a GCS to take authority from a companion computer.

Running SITL

ros2 launch ardupilot_sitl sitl_dds_udp.launch.py transport:=udp4 synthetic_clock:=True wipe:=False model:=quad speedup:=1 slave:=0 instance:=0 defaults:=$(ros2 pkg prefix ardupilot_sitl)/share/ardupilot_sitl/config/default_params/copter.parm,$(ros2 pkg prefix ardupilot_sitl)/share/ardupilot_sitl/config/default_params/dds_udp.parm sim_address:=127.0.0.1 master:=tcp:127.0.0.1:5760 sitl:=127.0.0.1:5501

mavproxy

param set RC6_OPTION 181
 reboot

Then use the CLI to test with joystick.

libraries/RC_Channel/RC_Channel.cpp Show resolved Hide resolved
libraries/AP_ExternalControl/AP_ExternalControl.h Outdated Show resolved Hide resolved
libraries/AP_ExternalControl/AP_ExternalControl.h Outdated Show resolved Hide resolved
@@ -740,8 +750,13 @@ void AP_DDS_Client::on_request(uxrSession* uxr_session, uxrObjectId object_id, u
break;
}

GCS_SEND_TEXT(MAV_SEVERITY_INFO, "%s Request for %sing received", msg_prefix, arm_motors_request.arm ? "arm" : "disarm");
arm_motors_response.result = arm_motors_request.arm ? AP::arming().arm(AP_Arming::Method::DDS) : AP::arming().disarm(AP_Arming::Method::DDS);
if (external_control->is_enabled()) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

We should ask the dev team whether they want to put arming in external control and push all control handover logic into external control for things like arming, mode change, joystick, etc.

Copy link
Contributor Author

@tizianofiorenzani tizianofiorenzani Oct 19, 2024

Choose a reason for hiding this comment

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

I would also ask the Dev team, what is the best way to add this functionality to the Ground Station? Maybe Using the Mavlink MAV_CMD_NAV_GUIDED_ENABLE message?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: 🏗 In progress
Development

Successfully merging this pull request may close these issues.

2 participants