Micrortps_bridge de/serialization mismatch

So I’ve spent a couple days trying to figure out why my offboard control isn’t working through the micrortps bridge to ROS2. My goal is to use ros2 to send body frame velocity commands to px4, and it does the low-level control of my rover.

I’m currently using px4 stable branch (commit a6274bc5 if you need it)

I’ve used the scripts and yaml file in msgs/Tools to generate the ros2 messages, topic ids, ros2 micrortps agent, etc. Just to ensure that my messages are compatible.

From what I understand about the rover position control module, I need to publish the PositionSetpointTriplet message, which crosses the bridge, the rover pos controller receives it, and does it’s thing. As far as I can tell, I’m successfully publishing the PositionSetpointTriplet from ros2, it’s traversing the bridge, and coming out as a uorb message. I can listener position_setpoint_triplet from nsh… but the data isn’t right…

The problem is it appears that the micrortps_agent Serialize function for PositionSetpoint looks like:

scdr << m_timestamp;
scdr << m_valid;
scdr << m_type;
scdr << m_x;
scdr << m_y;
scdr << m_z;
scdr << m_position_valid;
scdr << m_vx;
scdr << m_vy;
scdr << m_vz;
scdr << m_velocity_valid;
scdr << m_velocity_frame;
scdr << m_alt_valid;
scdr << m_lat;
scdr << m_lon;
scdr << m_alt;
scdr << m_yaw;
scdr << m_yaw_valid;
scdr << m_yawspeed;
scdr << m_yawspeed_valid;
scdr << m_landing_gear;
scdr << m_loiter_radius;
scdr << m_loiter_direction;
scdr << m_pitch_min;
scdr << m_a_x;
scdr << m_a_y;
scdr << m_a_z;
scdr << m_acceleration_valid;
scdr << m_acceleration_is_force;
scdr << m_acceptance_radius;
scdr << m_cruising_speed;
scdr << m_cruising_throttle;
scdr << m_disable_weather_vane;

While the position_setpoint_triplet.cpp deserialize in the micrortps_client looks like:

ucdr_deserialize_uint64_t(reader, &output->current.timestamp);
ucdr_deserialize_double(reader, &output->current.lat);
ucdr_deserialize_double(reader, &output->current.lon);
ucdr_deserialize_float(reader, &output->current.x);
ucdr_deserialize_float(reader, &output->current.y);
ucdr_deserialize_float(reader, &output->current.z);
ucdr_deserialize_float(reader, &output->current.vx);
ucdr_deserialize_float(reader, &output->current.vy);
ucdr_deserialize_float(reader, &output->current.vz);
ucdr_deserialize_float(reader, &output->current.alt);
ucdr_deserialize_float(reader, &output->current.yaw);
ucdr_deserialize_float(reader, &output->current.yawspeed);
ucdr_deserialize_float(reader, &output->current.loiter_radius);
ucdr_deserialize_float(reader, &output->current.pitch_min);
ucdr_deserialize_float(reader, &output->current.a_x);
ucdr_deserialize_float(reader, &output->current.a_y);
ucdr_deserialize_float(reader, &output->current.a_z);
ucdr_deserialize_float(reader, &output->current.acceptance_radius);
ucdr_deserialize_float(reader, &output->current.cruising_speed);
ucdr_deserialize_float(reader, &output->current.cruising_throttle);
ucdr_deserialize_bool(reader, &output->current.valid);
ucdr_deserialize_uint8_t(reader, &output->current.type);
ucdr_deserialize_bool(reader, &output->current.position_valid);
ucdr_deserialize_bool(reader, &output->current.velocity_valid);
ucdr_deserialize_uint8_t(reader, &output->current.velocity_frame);
ucdr_deserialize_bool(reader, &output->current.alt_valid);
ucdr_deserialize_bool(reader, &output->current.yaw_valid);
ucdr_deserialize_bool(reader, &output->current.yawspeed_valid);
ucdr_deserialize_int8_t(reader, &output->current.landing_gear);
ucdr_deserialize_int8_t(reader, &output->current.loiter_direction);
ucdr_deserialize_bool(reader, &output->current.acceleration_valid);
ucdr_deserialize_bool(reader, &output->current.acceleration_is_force);
ucdr_deserialize_bool(reader, &output->current.disable_weather_vane);

So it appears to me that the agent serializes the fields in a different order than the client is de-serializing them. I’m I reading this right?

Is there an easy fix for this? Or am I better off updating px4 to a newer version that may already have this fix for?

Thank you!

I ran into this same problem. I fixed it by switching the src/modules/micrortps_bridge/micro-CDR submodule link to the eProsima version of Micro-CDR/foxy at GitHub - eProsima/Micro-CDR at foxy.

If you switch to PX4 v1.12, the position_setpoint_triplet is no longer used for offboard setpoints, so this may also alleviate the problem.

This problem was already solved in upstream PX4 master.