# Cascading PID DC Motor Position & Velocity Controllers

I'm trying to build a robot with a differential drive powered by two DC motors. First I implemented a PID Controller to control the velocity of each motor independently. Estimated the TF using the MATLAB's System Identification Toolbox, of the open loop system by the acquiring the velocity of each wheels encoder in function of the PWM signal applied by an Arduino microcontroller. All went well and I successfully dimensioned the PID gains for this controller.

What I'm trying to accomplish now is to control the exact (angular) position of the DC motor. I thought in cascading a PID controller in the input of the other already implemented. So this way, I can give a position to the first controller, which will be capable of generate an output reference to the second (velocity) controller so it generates the appropriate PWM value signal to drive the DC motor accordingly.

Will it work? Is that a good approach? Or should I try to implement a different controller which outputs the PWM signal in response to a position reference signal?

• What feedback are you using for the motors? Jul 28, 2014 at 14:58
• At it stands, the question doesn't make much sense. How can you control the angular position of the motor at anything but zero velocity? If you want a motor to move from one position to another using a specific velocity profile, that is usually implemented by having a position-control loop, and feeding it a time-based series of positions generated by a profile generator. Jul 28, 2014 at 15:00
• Hi @Andyaka ! I'm using incremental positional hall-effect encoders. Aug 1, 2014 at 17:21
• I might be to late but your aproach is correct, also, you can cascade a torque controler to respond to load disturbances, also, you can use a optimal aproach to calculate gains of the controllers
– user120030
Aug 7, 2016 at 16:50

If you want to control position, control position. I don't see a point in having a intermediate velocity controller. That will make things more complicated and difficult to tune.

Since you apparently have position decoders, your control loop should be controlling for position directly. This control loop can then drive the motor harder when far from the desired position, and less so when close. If done right, this will implicitly result in a good velocity profile to get from one position to another.

If the higher level system wants the motors to run at a particular velocity, then it should ramp the desired position to the position controller.

Your approach should work. It's also the simplest way to solve the problem.

You could always work out a position controller that steers directly the motors, but it would be less easy to understand how to tune it. And I understand you have both position and velocity readings, so why not using two loops?

As people's comments to your question highlight, obviously you'd now have a position controller rather than velocity. But it makes sense as it's for a robot.

You need to be careful to a few details:

1. If the two DC motors are working in parallel, you must find a way for the two not to interfere with each other (like forcing load sharing). However you must have faced this problem already in the speed loop.
2. The external loop (position control) is bound to be far slower than the speed loop. If it worked at the same pace, or faster, you'd have the position loop strongly pulling on the speed one without letting it the time to react, and you'd have strong interactions or even instabilities. I suggest that you speed up the internal one (speed) as much as you can, and then tune the external one.
3. The external loop shall here be your 'precise' one. The internal one should just be quick in reaction rather than precise. I'd suggest a P or PD controller for the internal one, and PI or PID for the external one.

Extra tip: as it's for a robot, I'd take into consideration a position reference feed-forward.