Uav toolbox VTOL Ref.App Plant model with PX4 Sitl

68 views (last 30 days)
AbdulKadir
AbdulKadir on 11 Oct 2025 at 21:17
Commented: AbdulKadir on 14 Oct 2025 at 15:49
Hi. ı am trying to run Vtol plan model of Mathworks wıth PX4 sitl. I am taking HIL_ACTUATOR_CONTROL[16] array and using first 4 elements of it to conrol rotor of vtol. But when i observe the reponse of plant it was so late after i sent manual command from QGC. Almost seconds later and after a while uav will be out control and behaves independently from my commands. There is a big communication problem. How can solve that?
Thanks
  14 Comments
Umar
Umar on 14 Oct 2025 at 14:03

Hi @AbdulKadir,

Thanks for your patience. Let me walk through each of your observations step by step.

Comment #1: Understanding the actuator_controls Topic Issue

You're getting "Topic actuator_controls did not match any known topics" because this topic doesn't exist in the way you're trying to access it.Here's what's actually happening: In PX4's uORB messaging system, actuator_controls isn't a standalone topic you can listen to directly. Instead, you need to listen to one of these topics:

For HIL/SITL simulation (which is what you're running):

listener actuator_outputs_sim

For general actuator outputs:

listener actuator_outputs

The actuator_outputs_sim topic is specifically designed for SITL, HITL, and SIH (Simulation-In-Hardware) with an output range of [-1, 1], which matches what you're seeing in your rotor commands. This is documented in the PX4 uORB message reference: https://docs.px4.io/main/en/msg_docs/ActuatorOutputs.html

So try running:

   pxh> listener actuator_outputs_sim

This should show you exactly what PX4 is commanding to your motors in real-time. If you see the same 0-1 oscillations here that you're seeing in your Simulink model, then we know the problem is on the PX4 controller side, not in your plant or interface.

Comment #2: Your MAVLink Message Frequencies (30-50 Hz)

Looking at your QGC MAVLink Inspector screenshot, I can see: * ALTITUDE: 1.0 Hz * ATTITUDE: 40.2 Hz * ATTITUDE_QUATERNION: 40.2 Hz * ATTITUDE_TARGET: 40.2 Hz * GLOBAL_POSITION_INT: 39.4 Hz

This is completely normal. These are telemetry stream rates to QGC, not your internal simulation rates. Here's why: 1. Your internal PX4 simulation is running at 250 Hz (confirmed by your sensor_combined dt of 4000 microseconds) 2. Your HIL sensor updates from Simulink are also at 250 Hz (confirmed by the same dt) 3. But telemetry to QGC is intentionally downsampled to save bandwidth - attitude at 40 Hz, position at 40 Hz, and low-priority messages at 1 Hz

This is by design. PX4 doesn't send every internal update to QGC because: * It would overwhelm the MAVLink connection * QGC's UI only updates at 30-60 fps anyway * Bandwidth is limited, especially on radio links

So don't worry about the 30-50 Hz you're seeing in QGC - your simulation is still running at full 250 Hz internally.

Comment #3: CRITICAL Discovery in Your Sensor Data I noticed something very important in your sensor_combined output: gyro_rad: [-16.21060, -12.10875, -14.12814] accelerometer_m_s2: [-1.66517, 0.68474, -15.94180]

These gyro rates are extremely high! Specifically: * Roll rate: -16.2 rad/s ≈ -928 degrees/s * Pitch rate: -12.1 rad/s ≈ -693 degrees/s * Yaw rate: -14.1 rad/s ≈ -808 degrees/s

This means your vehicle is already spinning violently in your simulation, even before you command it to take off. A stable vehicle sitting on the ground (or hovering steadily) should show gyro rates close to zero, maybe ±0.1 rad/s at most.This confirms what you're experiencing - the "turning around itself" behavior. The vehicle is genuinely out of control, and these sensor readings prove it. The question is: why?

Comment #4: The Rotor Command Oscillations - This is Your Real Problem

You made a critical observation: "I also saw same response of rotor commands in a Quadcopter example which works properly. So i guess the response is normal but behaviour of Uav to this commands are not suitable"

You're absolutely right. If the quadcopter example shows similar command patterns but flies correctly, while your VTOL doesn't, then the issue is not the commands themselves - it's how your plant is responding to those commands. Combined with those massive gyro rates, this points to one primary issue: motor configuration mismatch.

Comment #5: "I tried to change rotation direction of rotors but it didn't work"

This is a crucial clue. Let me explain exactly what needs to be changed and why simply "reversing" motor direction often doesn't work: The Standard Quadcopter X Configuration:

  • Motor 1 (front-right): Counter-clockwise
  • Motor 2 (front-left): Clockwise
  • Motor 3 (rear-left): Counter-clockwise
  • Motor 4 (rear-right): Clockwise

What You Must Change in Your Simulink Plant Model:

When changing motor rotation direction, you need to modify TWO things simultaneously, not just one:

1. Thrust Vector (usually already correct):

% For all motors, thrust always points downward in body frame
Thrust_vector = [0; 0; -Thrust_magnitude];

2. Reaction Torque (this is what you probably missed):

% For CCW motors (1 and 3):
Torque_reaction = +K_torque * Thrust_magnitude;  % Positive = CCW
% For CW motors (2 and 4):
Torque_reaction = -K_torque * Thrust_magnitude;  % Negative = CW

The reaction torque is applied about the motor's axis (vertical Z-axis in body frame). This torque acts on the vehicle body in the opposite direction of the propeller spin.

Common mistake: People change the thrust vector direction or reverse the motor ordering, but forget to change the sign of the reaction torque. This causes exactly the spinning behavior you're seeing.

How to Verify Your Motor Configuration: In your Simulink plant model, find the section where motor forces and torques are applied to the 6DOF block. For each motor, verify:

Motor 1 (Front-Right): Position: [+L, -L, 0] % L = arm length Thrust: [0, 0, -T1] Torque: [0, 0, +K*T1] % Positive for CCW

Motor 2 (Front-Left): Position: [+L, +L, 0] Thrust: [0, 0, -T2] Torque: [0, 0, -K*T2] % Negative for CW

Motor 3 (Rear-Left): Position: [-L, +L, 0] Thrust: [0, 0, -T3] Torque: [0, 0, +K*T3] % Positive for CCW

Motor 4 (Rear-Right): Position: [-L, -L, 0] Thrust: [0, 0, -T4] Torque: [0, 0, -K*T4] % Negative for CW

Where K is your motor torque constant (typically 0.01 to 0.05 for small quads). If your torque signs don't match this pattern, that's why the vehicle spins uncontrollably.

Now some additional potential issues to consider

1. Motor Command Mapping

Verify that HIL_ACTUATOR_CONTROLS array indices map correctly: * HIL_ACTUATOR_CONTROLS[0] → Motor 1 (front-right) * HIL_ACTUATOR_CONTROLS[1] → Motor 2 (front-left) * HIL_ACTUATOR_CONTROLS[2] → Motor 3 (rear-left) * HIL_ACTUATOR_CONTROLS[3] → Motor 4 (rear-right) If these are swapped, even with correct torque signs, the vehicle won't fly correctly.

2. Thrust Scaling The actuator_outputs_sim outputs values in range [-1, 1]: * -1.0 = Full reverse thrust * 0.0 = No thrust * 1.0 = Full thrust

Your plant must map these to actual thrust. For most multirotors:

% Correct mapping:
Thrust_N = max(0, actuator_command) * Thrust_max;
% Or with quadratic relationship (more realistic):
Thrust_N = (max(0, actuator_command))^2 * Thrust_max;

If you're using a linear relationship when you should use quadratic, or vice versa, the controller gains will be mismatched.

3. Moments of Inertia

VTOL aircraft have different mass distributions than pure quadcopters. Your 6DOF block needs realistic inertia values:

% Typical small VTOL in quad mode:
Ixx = 0.01 to 0.05 kg⋅m^2 % Roll inertia
Iyy = 0.01 to 0.05 kg⋅m²^2 % Pitch inertia  
Izz = 0.02 to 0.08 kg⋅m^2 % Yaw inertia (usually highest)

If these are way off, the vehicle will respond too sluggishly or too aggressively.

So, here is summarized version of answers to your questions

1. "Is something missing with actuator_controls?"
No, nothing's missing. The topic name changed in newer PX4 versions. Use: listener actuator_outputs_sim This is the correct topic for SITL/HIL simulation and will show you the actual motor commands PX4 is sending.

2. "Why do frequencies change between 30-50 Hz in QGC?"
This is completely normal and expected. Those are just telemetry rates to QGC (downsampled to save bandwidth). Your internal simulation loop is still running at the full 250 Hz - confirmed by your sensor_combined dt of 4000 microseconds. No issues here.

3. "Same error continuous again"
The continuous blocks in your 6DOF dynamics are perfectly fine - don't change them. Those blocks represent physical dynamics which are naturally continuous. Only your interface blocks need to be discrete (0.004s), which you already have correct.

4. "Can I use PX4 Support Package for SITL without hardware?"
Yes, absolutely! Use "PX4 Host Target" mode - it runs PX4 SITL on your computer with no Pixhawk hardware needed. The UAV Toolbox Support Package specifically supports this. Try the MathWorks example: openExample('px4/MonitorTunePX4HostTargetFlightPlantModelExample') Or search for "Monitor and Tune PX4 Host Target with Simulink Plant Model" in MATLAB documentation.

5. "UAV behavior to commands is not suitable - spinning/uncontrolled"
Based on your massive gyro rates (-16 rad/s) and your observation that the quadcopter example works with similar commands, the problem is definitely in your plant model configuration. Most likely causes in order of probability:

1. Motor reaction torque signs are wrong (most common issue) 2. Motor position/ordering is incorrect 3. Thrust scaling doesn't match controller expectations 4. Inertia values are unrealistic 5. Wrong PX4 airframe/mixer configuration

So, please perform the following in order

Step 1: Verify What PX4 is Commanding pxh> listener actuator_outputs_sim Run this while commanding takeoff in QGC. Tell me: * Are the values smooth and reasonable (0.4 to 0.7 range for hover)? * Or are they oscillating wildly (0→1→0 square waves)? If they're smooth but your plant still spins, the problem is definitely in your plant. If they're oscillating, the problem is in PX4's controller tuning.

Step 2: Check Your Airframe Configuration pxh> param show SYS_AUTOSTART VTOL airframes should be: * 13xxx for Standard VTOL (QuadPlane) * 14xxx for Tailsitter VTOL * 15xxx for Tiltrotor VTOL If you're using 4xxx (standard quad), you need to change this. The mixer and control allocation will be wrong.

Step 3: Double-Check Motor Torque Signs

In your Simulink plant model, find where you apply motor torques to the 6DOF block. Print or log the torque values. Verify:

  • Motors 1 and 3 (front-right, rear-left): Positive torque about Z-axis
  • Motors 2 and 4 (front-left, rear-right): Negative torque about Z-axis If any of these are wrong, fix them immediately. This is almost certainly your issue.

Step 4: Compare with Working Quadcopter Example

Since you have Kiril Boychev's working quadcopter example: 1. Open that model 2. Find the motor torque application section 3. Note the exact torque signs and motor ordering 4. Compare with your VTOL plant 5. Make yours match exactly

Step 5: Test with Reduced Gains (Temporary Workaround) While you're debugging, you can reduce PX4's controller aggressiveness to make the vehicle more stable:

pxh> param set MC_ROLLRATE_P 0.05   # Default is usually 0.15
pxh> param set MC_PITCHRATE_P 0.05
pxh> param set MC_YAWRATE_P 0.1
pxh> param save

This won't fix the root cause, but it might make the vehicle controllable enough to test other things.

Given the complexity you're facing with manual MAVLink message handling and plant configuration, I strongly recommend switching to the official MathWorks UAV Toolbox approach. Here's why:

Current approach (manual): * You manually handle all MAVLink messages * You manually ensure timing synchronization * You manually configure motor mixing * You manually debug control issues * Any mismatch causes mysterious failures

Official UAV Toolbox approach: * Automatic MAVLink message handling * Built-in timing synchronization * Pre-configured motor mixing for standard vehicles * Better diagnostic tools * Works with PX4 SITL (no hardware needed)

The toolbox's "PX4 Host Target" mode is specifically designed for your exact use case - running PX4 SITL with a custom Simulink plant model. It eliminates 90% of the integration headaches you're experiencing.

To get started: 1. Install UAV Toolbox Support Package for PX4 Autopilots 2. Run: openExample('px4/MonitorTunePX4HostTargetFlightPlantModelExample') 3. Follow the example to connect your VTOL plant model 4. The toolbox handles all timing, messaging, and synchronization automatically Documentation: https://www.mathworks.com/help/supportpkg/px4/

Here is What I need from you To help diagnose this further, please share:

*Output of listener actuator_outputs_sim during a takeoff command (screenshot or copy-paste)

*Value of SYS_AUTOSTART parameter

*A screenshot or scope plot showing your 4 motor command values over 5-10 seconds

*If possible: The section of your Simulink model where motor torques are applied to the 6DOF block (just that subsystem, not the whole model)

With these pieces of information, I can pinpoint exactly which motor(s) have the wrong configuration and give you the precise fix.

Looking forward to hearing what you find! We're getting close to solving this - the sensor data tells us exactly what's wrong (vehicle spinning wildly), we just need to find which motor configuration is causing it.

P.S.- That -16 rad/s gyro rate you're seeing is actually helpful for debugging. When you fix the motor configuration, you should immediately see those rates drop to near-zero when the vehicle is sitting on the ground. That's how you'll know you've fixed it.

AbdulKadir
AbdulKadir on 14 Oct 2025 at 15:49
Hi Umar! I am grateful to you for this detailed response! I will try what you advise and write the results here.

Sign in to comment.

Answers (0)

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!