DC motor with encoders control


#1

Hello everyone,

We try to control two DC motors equiped with encoders and moto reductors using the controlled_motor_module (https://www.luos-robotics.com/en/documentation/controlled-motor/). It is not clear to us how we are supposed to work with this module (using pyluos) and we then have several questions :

r.controlled_mot0.positionPid = [3,0.002,100]
r.controlled_mot0.speedPid = [0.4,0.02,0]

how are we supposed to use the PID setup method ? what are supposed to mean P, I and D ?

what r.controlled_mot0. compliant() used for ?

When we launch

print (r.controlled_mot0.control())
before setting anything, power_mode is set as True

but, as soon as we do

r.controlled_mot0.trans_position_mode(True)
r.controlled_mot0.target_trans_position = 100.0
print (r.controlled_mot0.control())

power_mode seems to be set at False, even if we add

r.controlled_mot0.power_mode(True)

how is that possible ? Where do we get wrong ? is there any example of simple use of theses modules ?

Thank you for you help !
O.


#2

Hello,

PID?

The PID is for Proportional, Integral, Derivative. This is the coefficients used for the motor loopback.
Those coefs depend of your motors and your setup. You have to tune those values to have a stable position and speed on your setup.
Here is an article writen by @Simon with more complete explanations about it : https://medium.com/luosrobotics/an-introduction-to-pid-control-with-dc-motor-1fa3b26ec661

Compliant ?

This is used to enable or not the motor. At startup the motor is disable so you can move it by hand freely so it comply to your hand => it is compliant. I think you have the same kind of thing on MisBkit but you don’t call it the same.
To resume :

  • compliant = True => motor disable
  • compliant = False => motor enable
    So to make your motor move you have to disable compliant :
r.controlled_mot0.compliant = False

control mode ?

There is 3 way to control the movement of your motor :

  • power mode: This mode don’t use any feedback loop so no PID for this one you just control the power sent to the motor between -100.0% and 100.0%.
  • speed mode : This mode use feedback loop to maintain the motor speed as we target it regardless of disturbance. For this one you need to setup the speedPid. You control the speed of your motor in °/s. This mode is contradictory with the power mode, so when you enable it the module disable the power mode.
  • position mode : This mode use feedback loop to maintain the motor position as we target it regardless of disturbance. For this one you need to setup the positionPid. You control the position of your motor in °. This mode is contradictory with the power mode, so when you enable it the module disable the power mode.

Speed and position mode are not contradictory, you can enable both at the same time. When positionMode and speedMode are both enabled the motor module only use positionPid and control the speed of the motor using a motion planner algorithm.

Here is a small basic code allowing you to move (not perfectly because of not optimized PID) your motor :

# after connection
# ControlledMotor type settings
r.controlled_mot0.positionPid = [3,0.002,100] # position PID [P, I, D]
r.controlled_mot0.speedPid = [0.4,0.02,0] # speed PID [P, I, D]
r.controlled_mot0.encoder_res = 16 # Encoder resolution before reduction
r.controlled_mot0.reduction = 47 # gear reduction ratio of your motor
r.controlled_mot0.wheel_size = 100 # Wheel Diameter mm

# Motor control mode 
r.controlled_mot0.compliant = False # enable the motor
r.controlled_moto.rot_position_mode(True) # enable position mode so disable power mode
r.controlled_moto.rot_speed_mode(True) # enable speed mode
r.controlled_moto.target_rot_speed = 100.0 # set speed at 100°/s
r.controlled_moto.target_rot_position = 100.0 # set position in °

After execution of the # ControlledMotor type settings section, you should be able to do the other part of the code using the r.controlled_mot0.control() interface.


#3

Thanks for the answer !
We tried following your advices and it worked well.

:^)


#4

Bonjour,

Je me permets de rebondir sur la mail d’ @oliv1 concernant la gestion des DC motor.
@Nico : comment pouvons nous arriver à contrôler les 2 moteurs simultanément ? (en l’état nous émettons une commande target_trans_speed avec une vitesse pour chacun des moteurs avec une attente (sleep) entre les 2 appels). Dis autrement comment pouvons nous faire pour que les 2 roues de propulsions (avec chacune un moteur) démarrent ensemble ?

Plus généralement, comment faire pour être en capacité de paralléliser les appels au pyluos ? (en l’état les commandes moteurs et capteurs de distance doivent être envoyé en série avec des “sleep” pour ne pas saturer le canal)

Merci


#5

Sleep between commands

Why do you have to add sleep between commands? do you have any trouble if you don’t?
Pyluos pack simultaneous commands into a single Json and send it to the Luos network.
If your module revision is up to 0.3.0 your Luos network is able to understand multiple directive Json, and you should be able to send command as fast as you can without trouble.

How to synchronise messages

It’s a question I’ve been waiting for a long time, thank you for asking that.
Actually Pyluos only use something we call centralized “ID messages”.

“ID message” send a message to a single module so if you need to send the same massage to multiple module you have to do it multiple times.

Also Pyluos use the networks in a centralized way. Everything in the network is controlled by the gate connected to Pyluos. This gate is the bottleneck of the network bandwidth.

From now, nobody ask us about a more efficient way.
But the Luos network have other powerfull method to send messages :

  • Broadcast : send a message to all modules. This kind of message is secretly used when you start your network and make a detection
  • Multicast : send a message into a given topic and subscribers to this topic can get it.
  • Type : send a message to all modules of the same type. For example if you want to stop all your motors, you just have to send an unique disable compliance message to controlled_motors type.

Those message type are used in low level to do some network controls but they are not accessible through pyluos for now.

This kind of advanced messages are usefull for hard real time application where each microsecond counts.

With the centralized approach we can’t use 100% of the bandwidth because the central module have to prepare and manage messages and do a lot of other things. But in reality Luos is a decentralized bus each module can contact any module without asking permission to any other modules. This method allow to drastically reduce the number of message into the bus and allow to easily use 100% of the bandwidth of the network.

In your specific case

In you case you don’t really need all of this advanced real time stuff. Send 2 messages using Pyluos to 2 different motors (without sleep between them) create something like 2 or 3 ms of delay between motors which is insignificant compared to a mechanical movement.
Adding this kind of messages to Pyluos is a lot of work and make Pyluos a lot more difficult to master.
If you need to send the same message to multiple motors frequently I suggest you to create a function that will hide it to you.


#6

Hello,

Thank you for this complete answer!
We are currently with version 0.2 of the firmware; I understand that the version 0.3 offers additional possibilities, however question: you indicate “that it offers the possibility of sending several orders” is it transparent from our component ? How this sharing is done (should it be applied at the application level or is it integrated in your library ? ) In this second case is this integrated into your library ? is there a “buffer” mechanism to pool calls?

At this time it’s necessary to set pause at certain stages (and not chain several commands) if necessary the system hangs and either “some commands pass” or “a restart of the raspberry is necessary.”
Question: Is there an “acknowledgment” mode to get a feedback on the proper execution of the message ?

Regarding the synchronization of messages “uni, broad and multi”, I understand that we can currently use this, is this also the case with the updated versions of the firmware and the bookseller?

Thanks


#7

Pyluos send messages to the network each computer millis (if there is messages to send). So if there is multiple message request during this ms Pyluos will create a single Json with multiple command in it.
Your version of Pyluos do it for sure but your Gate revision 0.2 can’t manage multiple command Json. Indeed, this features appear on revision 0.3 (a new revision 0.4 appear yesterday).
So if you don’t place delay between command your gate only take one of your command and miss the others.

New revision are more stable, reliable and fast (we have to add a command to slow down Luos allowing computers to manage it). We are constantly improving software, I advise you to maintain you system up to date, you should switch to 0.4 firmware revision. This new revision need a recent revision of Pyluos (1.0.13) so you should update Pyluos too. Don’t worry Pyluos API did not change too much and you will be able to remove all your delay :wink: .

Pyluos can’t use those messages, there are only usable in embedded low level stage. For now only Luos staff can access this level (because it’s messy), but one day we will unleash it and make it accessible for users.


#8

Thank you for these elements !
Following my previous question is there a possibility of acknowledging messages ? (a confirmation that the order has passed and not missed as you indicated previously) ?


#9

Sorry I miss this one !
Pyluos don’t have any acknowledgement mechanism for now but Robus (Luos protocol) and Web socket have. The only weak point in it is the serial communication present on each Gate.
Until now I never see a message lost due to communication default.


#10

I came back on this one. Recently I make 2 robots for an exhibition and I observe some messages loss.
I have to spend time on it to find the real issue.