# Motor Control with PMW or RPM on heavy robot

I'm going to try to explain my problem as clearly as I can.

I have been building a robot that has four wheels, 2 motors and 2 free wheels. Its a differential drive system.

O --- O Motor Wheels
|     |
-o---o- Free Wheels.


The objective of this robot is to follow something/someone. I have cameras that give me a 3D point I use to define a position, and based on a setpoint, I correct the Front Error and Side Error with two PID controllers.

1 - Basic calculations to adjust robot are

Left Wheel = ( FrontError - SideError ) * Acceleration;
Right Wheel = ( FrontError + SideError ) * Acceleration;


Side Error and Front Error are results of Two different PIDs. One for each axis of a 3D coordinate space. Front is error on Z ( distance ), Side is error on X ( deviation from center ).

Q1: When I test the two PIDs independently, if only testing for front correction, or only side correction, everything works. But when I use the two PIDs I lose control of the robot. Any Idea why? Higher the speed the less control I have.

2 - I am controlling this through software on a computer, and sending those values to a board that controls the motors. What I am sending is PWM values. My problem is: since two motors are never equal, and depending on the load/weight the robot has on top of it, I need different PWM values for EACH wheel, for the robot to go forward. Sometimes, on a scale of 0-1023, if I set 150 PWM to one wheel and 400 to the other wheel, the robot doesn't turn as my calculations predict it would turn and goes straight forward.

Q2: When dealing with this kind of robots and control. What are the best way to solve this problem? I'm thinking of encoders. Controlling through RPM rather than PWM, and having a PID on each wheel on the motor controller board. Which leads to another issue. Lattency. I have a loop of 175ms. Taking that into account, what's the best solution for me?

• Latency of 175ms is huge; you ought to be able to bring that down a lot. You cannot add the output of PID controllers, as you've discovered - the algorithm assumes it has direct control of a variable. Feb 21, 2014 at 11:04
• Agreed, we control 3 motors on a 1ms interrupt loop with a mid-range 32-bit micro. However, going too fast can throw the PID loop into instability, going round the loop slower can have the effect of smoothing out high-frequency or transient errors and calming things down. Feb 21, 2014 at 12:52
• Sorry, I didn't make myself clear. I wanted to say that my main loop is fixed at 175ms. That is, I'm making all my calculations at that fixed rate. I am retrieving image information, getting user positions and then, caculate PIDs at that interval, then send speed to the motor control board Feb 25, 2014 at 11:23

Your second problem is probably closely related to the first. When you write the calculation:

Left Wheel = ( FrontError - SideError ) * Acceleration


what you really mean is:

Left Motor Input = ( FrontError - SideError ) * Acceleration


If there is a significant difference between the input to the motor and what the wheel actually does, perhaps because there is an unexpected load on the robot, then it is going to be difficult or impossible to tune those FrontError and SideError PID controllers in combination. If the wheel response is not linear you cannot simply add together two PID outputs and expect to have both work at once.

You have two general solutions here -- either develop a model so you can compensate for the difference, or make it so that the wheels actually respond fairly linearly to their input. This second option is probably the best one and it is what you will get if you use encoders and separate well-tuned PID controllers for each wheel.

Depending on all the other variables involved, the latency may prevent your control system from being stable. A simple two-pole PID controller might not be able to compensate adequately for it, but if you're experimenting it would be worth a shot, especially if you can fix up your wheel drives.

• Life is a Kalman filter ? :-) Feb 21, 2014 at 19:50

Your design is likely fighting itself. As soon as you enable the second PID controller your transfer function for the first PID is going to change drastically.

When just one PID controller is working error leads to a control decision made by that PID controller that is only met with a complacent robot frame that follows along. With a second PID every error leads to both PIDs making independent decisions. They are no longer met with a complacent robot frame, they are either fighting or amplifying each other.

All you really need to do in this case is to consider the system as a whole using vectors. The plant transfer function you want to use will take two voltage signals (x_1(t), x_2(t)) and output a position vector p(t).

I would formulate the PID controller/s in a different space, for example "heading space" and "velocity space." So there is one PID controller that "aims" towards the point, and another PID controller that "drives" towards the point. This way, they are orthogonal, and will not fight each other.

Additionally, for the robot to move straight when you say straight, you need some form of closed-loop control system. Optical or magnetic encoders on the wheels or on the motor shaft is typically used to make sure the motor runs at the speed you desire.

The P part of the PID controllers would be:

Delta Heading = (Desired Heading - Current Heading); // plus PID control
Delta Position = (Current Distance - Desired Distance); // plus PID control


You then derive the actual output values as:

Output Right = Delta Position + Delta Heading;
Output Left = Delta Position - Delta Heading;


Heading is the normal right-handed math-based heading, where bigger equals turning left.