-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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: Rally Get and Set #28449
base: master
Are you sure you want to change the base?
AP_DDS: Rally Get and Set #28449
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice addition, great to see some more interfaces like this.
The altitude needs a frame. |
@timtuxworth I have set the altitude frame explicitly now. |
8fb305b
to
7b5774b
Compare
As there is no code associated with the Rally flags, the DDS interface has been limited to only the Geopoint and the altitude frame |
0c549f9
to
e735057
Compare
Tools/ros2/ardupilot_dds_tests/test/ardupilot_dds_tests/test_rally_point.py
Outdated
Show resolved
Hide resolved
420c0d1
to
6dca61b
Compare
Rebased and pushed again. |
6dca61b
to
9fdff44
Compare
df289c2
to
76e08d0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Functionally, looks good. Just needs code cleanup and removal of potential link-flooding.
Tools/ros2/ardupilot_dds_tests/test/ardupilot_dds_tests/test_rally_point.py
Outdated
Show resolved
Hide resolved
7bcf60a
to
bee945e
Compare
@Ryanf55 suggestions applied, rebased and tested. |
08d2a04
to
3d943b9
Compare
} else { | ||
rally_location.lat = static_cast<int32_t>(rally_set_request.rally.point.latitude * 1e7); | ||
rally_location.lng = static_cast<int32_t>(rally_set_request.rally.point.longitude * 1e7); | ||
rally_location.alt = static_cast<int16_t>(rally_set_request.rally.point.altitude); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are implicitly losing precision and accuracy here. What should we do if the altitude is > 16 bits? Just silently truncate the value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Location is set to be integer, I need to pass values like this, the same as you do if it was the GCS to provide it.
libraries/AP_DDS/AP_DDS_Client.cpp
Outdated
rally_location.flags |= (rally_set_request.rally.altitude_frame << 3); | ||
|
||
if (rally_location.lat != 0 && rally_location.lng != 0 | ||
&& rally_set_request.rally.altitude_frame <= static_cast<uint8_t>(Location::AltFrame::ABOVE_TERRAIN)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand this test for altitude_frame being valid. Could you code it in a way that's clearer to understand what you are actually doing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That means the altitude enum is valid. I can re write it to check for each individual value, but I don't think it makes it more readable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@timtuxworth check it out now: I have explicitly compared it against every value in the enum.
Append a Rally Point: | ||
|
||
```bash | ||
ros2 service call /ap/rally_set ardupilot_msgs/srv/RallySet "{rally: {point: {latitude: -35, longitude: 151, altitude: 400}}}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be good to have an example with a frame supplied.
|
||
```bash | ||
ros2 service call /ap/rally_get ardupilot_msgs/srv/RallyGet "index: 0" | ||
requester: making request: ardupilot_msgs.srv.RallyGet_Request(index=0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it's something I need to understand about ROS, but how would you know if there is more than one rally point, there doesn't seem to be a request rally count message, do you just keep requesting indexes until you get a fail?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When you set a rally, it responds with the length of the Rally list. When you request a particular index, it fails if it does not exist. You can also use the service set call with an invalid point to obtain the length of the Rally list without adding any.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An AP might have previously been configured with zero, one or more rally points. After booting, the only way to find out if there are any rally points would be to start requesting them at the first and then incrementally keep requesting until you get a fail, or to request some really large index number (what the largest valid number +1?) to get the number.
I'm not sure I understand how that's ok.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that we should ensure this API works if there are pre-existing rally points. A sequence diagram could be helpful
ardupilot_msgs.srv.RallySet_Response(success=True, size=0) | ||
``` | ||
|
||
Append a Rally Point: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would probably be good to show fractional lat/long and be clear that the altitude is meters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have to show units of measure when in SI?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think so because unfortunately some ArduPilot metrics are not SI (it's a work in progress).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no problem, I can update the readme.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this README needs an update now that you removed some of the flags and optional features.
Regarding units, the DDS interface follows ROS REP-103. Units are SI unless otherwise stated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Ryanf55 the Readme has been updated.
geographic_msgs::msg::GeoPoint point; | ||
|
||
uint8 altitude_frame; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where are break_altitude, land_dir, flag_favorable_winds, flag_do_auto_land?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They have been removed, as not used. It was agreed in the dev call.
rally_get_response.rally.altitude_frame = (rally_location.flags >> 3) & ((1 << 2) - 1); | ||
} else { | ||
rally_get_response.rally.altitude_frame = static_cast<uint8_t>(Location::AltFrame::ABOVE_HOME); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where are break_altitude, land_dir, flag_favorable_winds, flag_do_auto_land?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are not used anywhere in the code and have been removed. We discussed about that in the dev call.
} else { | ||
rally_set_response.success = false; | ||
} | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where are break_altitude, land_dir, flag_favorable_winds, flag_do_auto_land?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are no where to be used in the code and have been removed.
ba5d645
to
0b91c49
Compare
Rebased, ready for another round. |
0b91c49
to
dd3576f
Compare
Issue
#28444
What Changed
/ap/rally_set
appends a Rally Point to the list or clears the list (using theclear
flag).point
: geolocationaltitude_frame
mandatory, follows enum of AltFrame.success
is the action is successful;size
is the list's size./ap/rally_get
gets the Rally Point at a given index. Returns:success
rally
the rally point asardupilot_msgs/Rally
type.ardupilot_msgs/Rally
type is defined, that copies the structure definition inAP_Rally
.Test
Auto Test
Manual Test
ros2 service call /ap/rally_set ardupilot_msgs/srv/RallySet "{clear: true}"
ros2 service call /ap/rally_set ardupilot_msgs/srv/RallySet "{rally: {point: {latitude: -35.36, longitude: 149.17, altitude: 400}}}"
ros2 service call /ap/rally_get ardupilot_msgs/srv/RallyGet "index: 0"