Electronic – arduino – Cascading PID DC Motor Position & Velocity Controllers

arduinocontrol systemdc motormobile robotpid controller

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?

Best Answer

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.