Omnicopter Simulation in Gazebo

Issue: PX4 v1.14.0 + ROS 2 Foxy + Micro XRCE DDS: Deserialization Errors and Incorrect Thrust Setpoints in Omnicopter Simulation

System Configuration:
PX4 Autopilot: v1.14.0 (HEAD detached at tag v1.14.0)
ROS 2 Foxy (ROS_DISTRO=foxy)
Gazebo Simulator: Gazebo Classic 11.11.0
Operating System: Ubuntu 20.04 LTS
|PX4 Target: px4_sitl with gazebo-classic_omnicopter
Micro XRCE DDS Agent: Built and run manually from source (latest tag)
PX4 Transport Mode: microDDS client with micrortps_bridge

Objective:

I am attempting to simulate a custom Omnidirectional Multirotor (Omnicopter) model using PX4 with ROS 2 Foxy and Gazebo Classic. The goal is to perform offboard control via a ROS 2 node that sends vehicle_attitude_setpoint and vehicle_thrust_setpoint messages.

Problem Summary:

Although PX4 enters offboard mode and arms successfully, the drone exhibits unstable behavior:

The drone flips to one side as soon as the offboard mode begins.
PX4 reports no z-thrust component even though the ROS 2 node sends thrust in the -z direction.
PX4’s listener vehicle_thrust_setpoint shows z = 0.0 constantly.
A persistent deserialization error appears on the ROS 2 side from Micro XRCE DDS Agent.

This suggests that the data being sent from ROS 2 is not correctly interpreted by PX4.

ROS 2 Offboard Node Output
ros2 run offboard_path offboard_ctrl_omni

Produces repeated logs:

[INFO] [offboard_control_omni]: Switching to offboard mode
[INFO] [offboard_control_omni]: Arm command sent
Sending thrust:  -0.9
Sending thrust:  -0.9
...
[SUBSCRIBER Error] Deserialization of data failed -> Function deserialize_change

I confirmed that /fmu/in/vehicle_attitude_setpoint and /fmu/in/vehicle_thrust_setpoint are being published by ROS 2.

PX4 receives the topic, but listener vehicle_thrust_setpoint in the PX4 shell shows incorrect values, particularly a zero z-thrust.

PX4 Shell Observations:

Inside the PX4 shell (pxh>) after the ROS 2 node starts:

vehicle_status shows the vehicle is armed and in offboard mode.
vehicle_control_mode shows offboard is enabled.
vehicle_attitude_setpoint values are populated.
vehicle_thrust_setpoint always shows zero for the z-component.
estimator_status and vehicle_odometry are normal.

Additional Details:
The offboard node sends:
thrust.z = -0.9
Attitude quaternion corresponding to hover (flat orientation).
PX4 flips to one side due to lateral-only thrust and missing upward thrust.
Visual odometry is correctly published to /fmu/in/vehicle_visual_odometry, and EKF2 is using it for pose estimation.

The DDS agent is run as:
./MicroXRCEAgent udp4 -p 8888

The ROS 2 odometry bridge node is run as:
ros2 run odom_to_px4_bridge odom_bridge_node

The offboard controller node is:
ros2 run offboard_path offboard_ctrl_omni

I think:

  1. There is a struct mismatch or padding/byte order issue in the IDL definition of vehicle_thrust_setpoint, causing PX4 to interpret incorrect values.
  2. The DDS deserialization error indicates that the payload sent from the agent is corrupted or truncated.
  3. PX4 is expecting the message in a specific alignment that is violated in the ROS 2 message or Micro XRCE transport.

Request for your Help:

  1. What steps can we take to verify and debug the deserialization error (deserialize_change) in the Micro XRCE DDS Agent?
  2. Is this a known issue with vehicle_thrust_setpoint in PX4 v1.14.0 with ROS 2 Foxy?
  3. Can you confirm whether this combination of PX4 and ROS 2 is expected to work for vehicle_thrust_setpoint and vehicle_attitude_setpoint over Micro XRCE DDS?
  4. Are there known examples or working setups for offboard control using ROS 2 and Micro XRCE DDS with custom vehicle models like the Omnicopter?
  5. If not feasible via this route, is there an alternative method to simulate an Omnicopter with offboard control using PX4?

I am open to verifying any message definitions, or modifying the Micro XRCE Agent if required. Let me know if log files or additional tests would help.

Thank you for your time and support.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.