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: Add dynamic TF subscriber support for odometry #24155
Conversation
Ryanf55
commented
Jun 28, 2023
- This is the first step for GSOC Cartographer external odometry input
Thanks for the help! I have a few suggestions, tell me if they are in the scope of this PR |
Not sure if you meant to add anything, please share when you get time. |
If we use the |
.topic_profile_label = "dynamictransforms__t", | ||
.dw_profile_label = "", | ||
.dr_profile_label = "dynamictransforms__dr", |
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.
Changes to make it consistent with dds_xrce_profile.xml
:
.topic_profile_label = "dynamictransforms__t", | |
.dw_profile_label = "", | |
.dr_profile_label = "dynamictransforms__dr", | |
.topic_profile_label = "dynamictf__t", | |
.dw_profile_label = "", | |
.dr_profile_label = "dynamictf___dr", |
An error was appearing before and the subscriber wasn't created. With this changes it is now working:
This should solve the test dds / build (stm32h7) (pull_request)
CI fail
Some updates from today's meeting regarding external odometry input into ArduPilot libs: Add Ap_VisualOdom.h, add support in handle_vision_position_estimate with a Vector3F pos (which is either single or double precision depending on the platform). To start, do it with single precision, and upgrade it later? This would be an extreme ardupilot sort of feature at distances >100km. For GSoc, let's ignore it. For home vs origin, see writeExtNavData. Users can set home mid mission, while the ROS convention specifies that origin and map are static. Within the EKF, there is a public orign (exposed to AHRS), absolutely static till reboot. Shadow origin is updated internally updated at 1Hz to current vehicle location. This deals doesn't deal with flat earth well. For setting the origin, there is a mavros way to do it set_origin.py. Ardupilot only requires a global origin, not GPS. Pedro sets origin manually in a script. This would be a good service if we want a pure ROS solution. OR, assume we initially have GPS then lose GPS and use vision. Either solution is OK for Tridge. Pedro can time to look into it. Tridge recommends just doing the GPS method because it's easier to initialize the EKF. Without GPS, the EKF gets stuck waiting for lag to determine its buffer size. For the time between sensor measurement and position estimate, it needs to be under 250mS due to Ardupilot EKF. Fusion is max 100Hz, and that is when the forward propogation happens. Further than 250mS, it degrades a t^2 and linear CPU increase. For high lag data, there is a different API (recent addition).See AP_NavEKf3. See AP_NavEkf3_PosVelFusion with the EK3_FEATURE_POSITION_RESET. Later, we could support downsampled velocity history. Action for pedro: Benchmark the algorithm on hardware, then we can decide. In SITL testing, GPS_DELAY_MS could be bumped up to match the vision estimate issue. Paul put this to save RAM, but it's problematic for dual GPS. Current behavior fixes it by clamping the timestamp and fuses at the wrong time. TBD what the behavior for vision is. In EKF source selection, set primary to GPS, secondary to Vision, and then use RC or Lua to switch if we required GPS lock. Once we get logs working, ping Tridge to review how to look at EKF innovations and |
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.
libraries/AP_DDS/AP_DDS_Client.cpp
Outdated
uint32_t* count_ptr = (uint32_t*) args; | ||
(*count_ptr)++; | ||
if (rx_dynamic_transforms_topic.transforms_size > 0) { | ||
GCS_SEND_TEXT(MAV_SEVERITY_INFO,"Received tf2_msgs/TFMessage of length: %lu", |
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.
GCS_SEND_TEXT(MAV_SEVERITY_INFO,"Received tf2_msgs/TFMessage of length: %lu", | |
GCS_SEND_TEXT(MAV_SEVERITY_INFO,"Received tf2_msgs/TFMessage of length: %u", |
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.
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.
After building ardupilot
and ardupilot_sitl
I ran the iris_maze
launch from ardupilot_gz
. In order to test the tf subscriber, I remapped the robot_state_publisher
node from /tf
to /ap/tf
.
AP_DDS_Client
received a message but this apparently caused a seg fault, any idea why that might be? Here's the log:
[dds_udp.parm --synthetic-clock -4] ERROR: segmentation fault - aborting
[dds_udp.parm --synthetic-clock -4] Running: sh dumpstack.sh 97015 >dumpstack.sh_arducopter.97015.out 2>&1
[mavproxy.py --out 127.0.0.1:14550 --out 127.0.0.1:14551 --master tcp:127.0.0.1:5760 --sitl 127.0.0.1:5501 --non-interactive -5] AP: Received tf2_msgs/TFMessage of length: 6
[dds_udp.parm --synthetic-clock -4] Failed
[dds_udp.parm --synthetic-clock -4] Running: sh dumpcore.sh 97015 >dumpcore.sh_arducopter.97015.out 2>&1
[dds_udp.parm --synthetic-clock -4] Failed
[dds_udp.parm --synthetic-clock -4] Aborted (core dumped)
[ERROR] [dds_udp.parm --synthetic-clock -4]: process has died [pid 97012, exit code 134, cmd 'arducopter --model json --speedup 1 --slave 0 --sim-address=127.0.0.1 --instance 0 --defaults /home/fuoco/ros2_ws/install/ardupilot_sitl/share/ardupilot_sitl/config/default_params/gazebo-iris.parm,/home/fuoco/ros2_ws/install/ardupilot_sitl/share/ardupilot_sitl/config/default_params/dds_udp.parm --synthetic-clock '].
[mavproxy.py --out 127.0.0.1:14550 --out 127.0.0.1:14551 --master tcp:127.0.0.1:5760 --sitl 127.0.0.1:5501 --non-interactive -5] EOF on TCP socket
[mavproxy.py --out 127.0.0.1:14550 --out 127.0.0.1:14551 --master tcp:127.0.0.1:5760 --sitl 127.0.0.1:5501 --non-interactive -5] Attempting reconnect
[mavproxy.py --out 127.0.0.1:14550 --out 127.0.0.1:14551 --master tcp:127.0.0.1:5760 --sitl 127.0.0.1:5501 --non-interactive -5] [Errno 111] Connection refused sleeping
[mavproxy.py --out 127.0.0.1:14550 --out 127.0.0.1:14551 --master tcp:127.0.0.1:5760 --sitl 127.0.0.1:5501 --non-interactive -5] [Errno 111] Connection refused sleeping
[mavproxy.py --out 127.0.0.1:14550 --out 127.0.0.1:14551 --master tcp:127.0.0.1:5760 --sitl 127.0.0.1:5501 --non-interactive -5] Attempting reconnect
The crash doesn't happen if I don't remap the topic (presumably because nothing reaches the subscriber handler)
@pedro-fuoco have you tried publishing TF from the command line? ros2 topic pub /ap/tf tf2_msgs/msg/TFMessage 'transforms: [{header: {stamp: {sec: 1, nanosec: 0}, frame_id: "base_link"}, child_frame_id: "GPS_0", transform: {translation: {x: 0.0, y: 0.0, z: 0.0}, rotation: {x: 0.0, y: 0.0, z: 0.0, w: 1.0}}}, {header: {stamp: {sec: 2, nanosec: 0}, frame_id: "base_link"}, child_frame_id: "GPS_0", transform: {translation: {x: 0.0, y: 0.0, z: 0.0}, rotation: {x: 0.0, y: 0.0, z: 0.0, w: 1.0}}}, {header: {stamp: {sec: 3, nanosec: 0}, frame_id: "base_link"}, child_frame_id: "GPS_0", transform: {translation: {x: 0.0, y: 0.0, z: 0.0}, rotation: {x: 0.0, y: 0.0, z: 0.0, w: 1.0}}}, {header: {stamp: {sec: 4, nanosec: 0}, frame_id: "base_link"}, child_frame_id: "GPS_0", transform: {translation: {x: 0.0, y: 0.0, z: 0.0}, rotation: {x: 0.0, y: 0.0, z: 0.0, w: 1.0}}}, {header: {stamp: {sec: 5, nanosec: 0}, frame_id: "base_link"}, child_frame_id: "GPS_0", transform: {translation: {x: 0.0, y: 0.0, z: 0.0}, rotation: {x: 0.0, y: 0.0, z: 0.0, w: 1.0}}}]' --once I'm running a rebased version of the PR with the fixes you noted included: https://github.com/srmainwaring/ardupilot/tree/wips/wip-tf-subscriber-rebased-fixes Update
ros2 launch ardupilot_gz_bringup iris_runway.launch.py` I suspect it's a combination of the message size and rate.
Run SITL session (no Gazebo): ros2 launch ardupilot_sitl sitl_dds_udp.launch.py transport:=udp4 refs:=$(ros2 pkg prefix ardupilot_sitl)/share/ardupilot_sitl/config/dds_xrce_profile.xml 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 Send single TF (6 items of the 8 published from the iris example): ros2 topic pub /ap/tf tf2_msgs/msg/TFMessage 'transforms: [
{header: {stamp: {sec: 227, nanosec: 91000000}, frame_id: iris}, child_frame_id: iris/tilt_link, transform: {translation: {x: 0.019984060916003184, y: -0.020015926647110993, z: -0.09998399286175172}, rotation: {x: -0.4999997609802308, y: 0.49999975742835057, z: 0.4996019204931798, w: 0.5003982440325244}}},
{header: {stamp: {sec: 227, nanosec: 91000000}, frame_id: iris}, child_frame_id: iris/roll_link,
transform: {translation: {x: -2.2827193214895528e-11, y: -2.3581028733108545e-08, z: -0.09999990013228542}, rotation: {x: 0.0002823774170257476, y: 0.7068251247013926,
z: -0.0002807098464664981, w: 0.70738821346969}}},
{header: {stamp: {sec: 227, nanosec: 91000000}, frame_id: iris}, child_frame_id: iris/gimbal_link, transform: {translation: {x: -7.861318384707755e-19, y: -0.01, z: -0.11}, rotation: {x: 0.5000000095078997, y: 0.4996016684687246, z: 0.500000009775746, w: 0.500397995179458}}},
{header: {stamp: {sec: 227, nanosec: 91000000}, frame_id: iris}, child_frame_id: iris/rotor_0, transform: {translation: {x: 0.13000000000182527, y: -0.2199999999962856, z: 0.023000096313720075}, rotation: {x: -6.217004150247587e-12, y: 1.5109553369859743e-12, z: -0.00010602049440067152, w: 0.9999999943798272}}},
{header: {stamp: {sec: 227, nanosec: 91000000}, frame_id: iris}, child_frame_id: iris/rotor_1, transform: {translation: {x: -0.12999999999845072, y: 0.20000000000354365, z: 0.023000096309283957}, rotation: {x: -6.217004150247587e-12, y: 1.5109553369859743e-12, z: -0.00010602049440067152, w: 0.9999999943798272}}},
{header: {stamp: {sec: 227, nanosec: 91000000}, frame_id: iris}, child_frame_id: iris/rotor_3, transform: {translation: {x: -0.12999999999818787, y: -0.1999999999964565, z: 0.02300009631425745}, rotation: {x: -6.217004150247587e-12, y: 1.5109553369859743e-12, z: -0.00010602049440067152, w: 0.9999999943798272}}}]' --once Additional notes:Using # throttle from 1000 Hz to 1 Hz and relay to /ap/tf
ros2 run topic_tools throttle messages /tf 1 /ap/tf |
01bf723
to
f1e871e
Compare
libraries/AP_DDS/AP_DDS_Client.cpp
Outdated
uint32_t* count_ptr = (uint32_t*) args; | ||
(*count_ptr)++; | ||
if (rx_dynamic_transforms_topic.transforms_size > 0) { | ||
GCS_SEND_TEXT(MAV_SEVERITY_INFO,"Received tf2_msgs/TFMessage of length: %zu", |
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.
Apparently the Ardupilot C compiler doesn't support %z
. It failed CI and I also wasn't able to compile it locally.
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.
Which board is it failing for you on?
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.
Pixhawk4
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.
With the last commit, it passes CI with the use of a static cast.
Please approve if you are happy.
Tested it with the |
* This is the first step for GSOC Cartographer external odometry input * Moved subscriber data members to class member variables Signed-off-by: Ryan Friedman <ryanfriedman5410+github@gmail.com>