Implementing a multicopter custom controller with 6DOF desired vector (forces and moments) [From Slack]

Salvatore Marcellini asked:
Hi guys, i am trying to implement my multicopter custom controller that uses a 6D desired vector (3 forces and 3 moments), that has to be mapped on both motors and servomotors. I would understand how i can change the mapping and if there is already a uORB topic that allows to send a 6D desired vector.

Junwoo:
That is achievable with the new Control Allocation!
Check out the doc here: Actuator Configuration and Testing | PX4 User Guide

Salvatore:
i’ve read the documentation about the new control allocation but i think that it is not what i needed maybe.
I have a tilt-rotor multicopter and i want to write my custom control that sends the velocity of each motor and the tilt angle of the servomotor.
With the new actuator control i can set the motors and servomotors but the speed of each motor(propeller) will be different from the standard flat multicopter bacause of the tilti angle, so i need to publish the desired velocity to each motor(propeller).
Otherwise i need to create a new mapping function for the mixer, i think.
Do you have any advice for me please?

Junwoo:
Hmm gotcha, so you don’t want to use the Multicopter Attitude Control logic in PX4 right? Then, it would basically involve writing up all the control algorithms and then sending actuator commands to motor / servos.
Since you said in the beginning you want to specify torque & force setpoint in 6DOF for control, I thought Control Allocation is a good option (as you command the 6DOF, and the control allocator module decides which output to allocate on each actuators), but for your case it seems like you want to do everything on your own from controls to actuator outputs :thinking_face:, is that correct?

Salvatore:
Yes, if its not possible with the feature that are already implemented.
I just changed the equations in the mc_position, mc_attitude and mc_rate controllers. But i have the problem with the actuator outputs

This is a conversation / thread from Slack, ported over to Discuss Forum for future preservation of knowledge

@salmarc So currently, I assume that you will have arrived at this part in Multicopter-Rate-Control module, where it actually publishes the torque and force setpoints:

Now there can be two ways of dealing with your custom multicopter with servo-actuable motors:

  1. Bypass the control allocator module and set the actuator output directly in your own custom module (or in the Multicopter Rate Control)

This would be the must simple way to do it, but in the end you will be bypassing the control_allocator module, by translating the vehicle_torque_setpoint and vehicle_force_setpoint into a feasible servo/motor output and publishing it into actuator_motors and actuator_servos.

  1. Select the ‘Custom’ airframe type for Control Allocator, and map each Servo to the Motor, defined by it’s custom axis

This would be a more ‘modern’ version, but of course you will then be giving up the exact control authority on individual servo and motors (which you can only achieve by directly controlling the actuator_motors and actuator_servos topic, and disabling the control_allocator)

If anything is unclear, please let me know! And I am also not 100% knowledgable about this topic, so am happy to learn together and have your project work out! :wink:

If i use this method, will it bypass all the safety control? and for example will i loose some normal functions of PX4?

I think that it cannot be the solution because i don’t know if the allocator will take in account the movement of the servo. I will explain myself better: if the motor 1 is spinning at 1400 PWM for example and i tilt the servo that moves the motor 1, in order to have the same vertical thrust but with the tilted motor, the pwm will be maybe 1450 or 1500 (depends).

Is it hard to create a new allocator that takes as input a 6D force vector (forces and moments) and depending on the geometry of the drone (or for example just using a fixed geometry to start), mixes the desired pwm to servos and motors?

I know really few so i really want to learn :slight_smile:

Well thats exactly what a control allocator does! It can take into account the Servo’s tilt angle to modify the control effectoveness matrix (which defines what force and torque gets applied with a given commands to the motors.

Yes but if i’m not wrong, the control allocator for a multicopter doesn’t take into account the tilt angles of the servo, does it?
I’m inside a limbo where i know what has to be done but don’t know how to integrate that in px4 :sweat_smile:

Yes you are correct! So using the multicopter control allocator, you won’t be able to assign the servos & make it actuate the motors.

Therefore, you will need to select CUSTOM airframe via the parameter CA_AIRFRAME, and then map the servos and motors and assign there geometry!

Oh actually, you can select Multirotor with Tilt airframe that is already supported, and have motor & tilt servo combination like this already setup!

The way to do this is:

  1. Set CA_AIRFRAME to Multirotor with Tilt
  2. Reboot the vehicle
  3. Go to Vehicle Settings > Actuators Tab in QGC, and configure

However, I am noticing that The tilt directions for servos are confined to Front or Right. In case you want to tilt towards something in the middle (front/right 45 degrees), that isn’t currently supported.

Let me know if this helps!

1 Like

I think this one is for bicopter with tilting motors, and maybe that’s why they can be mounted only front or right.
This can be a good starting point maybe, but the drones that i use for my PhD research are usually with X configuration and the tilt are used for all rotations (roll, pitch and yaw) while with this interface i can select only pitch and/or yaw

By the way, here’s a documentation of the control allocation that I think will help you in getting your controller implemented!

Checkout this section to learn how to implement your custom geometry / output function :smile:

1 Like

So I think you can add a new geometry of a multicopter something like this:

/**
 * @file ActuatorEffectivenessTiltrotorMulticopter.hpp
 */

#pragma once

#include "ActuatorEffectiveness.hpp"
#include "ActuatorEffectivenessRotors.hpp"

#include <uORB/topics/actuator_controls.h>
#include <uORB/Subscription.hpp>

class ActuatorEffectivenessTiltrotorMulticopter : public ModuleParams, public ActuatorEffectiveness
{
public:
	bool getEffectivenessMatrix(Configuration &configuration, EffectivenessUpdateReason external_update) override;

	void updateSetpoint(const matrix::Vector<float, NUM_AXES> &control_sp, int matrix_index,
			    ActuatorVector &actuator_sp) override;

	uint32_t getStoppedMotors() const override { return _stopped_motors; }

protected:
	ActuatorEffectivenessRotors _mc_rotors;
	ActuatorEffectivenessTilts _tilts;
};

And to obtain the direct control of the actuators, you can utilize the updateSetpoint function, like the way helicopter’s case is handled.

Hope this helps!

1 Like