Integrating L1 Adaptive Control with MPC for Quadrotor in ROS 2 and PX4

Hi everybody,

I am currently developing an outer loop Model Predictive Controller for a quadrotor, my next step includes adding an L1 adaptive controller to it, just to test how L1+MPC would fare in a quadrotor implementation.

Since the L1 would work as an addition to the output of the MPC (thrust and quaternion reference) and right now the controller is publishing on the VehicleAttitudeSetpoint topic I was thinking how to implement it.

I was thinking it would be nice to implement the L1 as a standalone ROS 2 node, the MPC basically would work in the same way as it does not know that the L1 is active. In this way both would publish the attitude reference (and thrust).

Basically what I am asking if anyone know if there is a way for the L1 controller to “catch” the output of the MPC and add or subtract the control effort. Both node would be implemented as ROS 2 nodes.

I was thinking that would be nicer for debug purposes and rqt visualization. Otherwise I would implement this as a ROS2 parameter enabled flag and the L1 adaptation would reside in the NMPC node.

Thanks in advance,
Let me know if any more info has to be taken into account.

Riccardo

1 Like

Hi,I am currently planning to implement L1 adaptive control based on the PX4 firmware and would greatly appreciate your insights on a few aspects. I noticed that your approach outputs thrust and quaternion, while most quadrotor L1 adaptive control implementations I’ve encountered focus on thrust and torque. Could you kindly share what uncertainties you have taken into consideration in your work? Thank you very much for your help!

Hello, the goal is to use a “Position” MPC that outputs thrust and a quaternion as an attitude reference. The attitude control loop is managed by a geometric controller (essentially a PID) with an L1 augmentation. In this setup, the output of the geometric controller + L1 would be thrust and torque, as you’ve seen.

How about publishing the the thrust and quaternion computed by MPC to some custom topic and letting the L1 aug node subscribe this topic?

By the way, I also want to test control performance using thrust and torque. However, VehicleThrustSetpoint and VehicleTorqueSetpoint require normalized values. To send thrust and torque commands, how to you do the normalization?

Currently, I make a control allocator myself and convert the thrust and torque to rotor commands (PWMs) and use ActuatorMotors. But the drone just crashes… The frequency of publishing the ActuatorMotors messages is about 100Hz. Maybe I should make it faster?

May I know what px4 version you are using to publish to ActuatorMotors? Are you setting it to offboard mode before publishing it to the motors? Is it ROS1 or ROS2?

  1. px4 1.15.0
  2. yes
  3. ros2

Thank you, @Xiaowei. Did you test this on an actual drone? I am also trying to actuator control using 1.14.2, but it goes into a failsafe mode when I stop publishing the motor commands. I have to restart the autopilot to be able to send control commands again. Are you facing this kind of problem with 1.15.0? If not, I will also switch to 1.15.0.

You are welcome. Yes, I did some experiments on a real drone, but the drone always crashed. I am examining that.

I am not facing the problem you describe here. Are you publishing the motor commands in the offboard flight mode? If so, you also need to publish OffboardControlMode messages with at least 2Hz.

Are you able to control the drone to hover or track some reference trajectory by directly publishing motor commands?

Yes, I am publishing motor commands in offboard mode. I just managed to do a short lift-off for one second and cut off the throttle. I haven’t continued flying as the controller wasn’t ready. I also noticed that it is going into a failsafe mode if the thrust command to a motor is less than 0.1.

I am yet to design a controller for hovering and trajectory tracking, but before I want to make sure that the communication is robust and the setup is correct. I will also upgrade to 1.15 and see if this problem can be fixed. Did you custom-compile the firmware or use the one provided by px4?

I could do position control in offboard mode by publishing position setpoints. I think I can do trajectory tracking by publishing normalized total thrust and angular rates, which I did with ROS1 and Mavros.

I also noticed that it is going into a failsafe mode if the thrust command to a motor is less than 0.1.

I haven’t noticed this. Thanks for your info.

Did you custom-compile the firmware or use the one provided by px4?

I just use the one provided by px4.

I also could do position control in offboard mode by publishing position setpoints. Since my controller contains total thrust and torque, I want to send these commands, but px4 needs their normalized values. Do you know how to normalize the total thrust and torque?

I have tried sending PWM signals using the ActuatorMotors message from a raspberry pi through ROS2 with 100hz. The drone always crashed. Is it possible to send PWMs using ROS2?

You can check my paper to see how I am normalizing the thrust and controlling the drone. I was determining a scaling factor first and then using it to normalize the accelerations. But, this one was implemented using ROS1 and mavros. I was using the output of ROS topic /mavros/target_actuator_control. This topic is not available in ROS2. I am not able to calculate the scaling factor in ROS2

ASTC Paper

If it is not clear how to calculate the normalized thrust, let me know. I don’t know how to normalize torques.

I commanded to /fmu/in/actuator_motors which is of ActuatorMotors message type you are also using. For this message type, you cannot send PWM values. You can only send normalized thrust which should be between 0 and 1.

1 Like

FYI, here is an example of an MPC implementation integrated with PX4 using acados: Here is an example: GitHub - Jaeyoung-Lim/px4-mpc: MPC implementation using acados integrated with with PX4 on ROS2

1 Like