2
$\begingroup$

I am trying to use a PID loop to control a motor. This is my first attempt at creating a PID loop (really just a PI loop). There doesn't exist a model for this system, and I don't know how to create one. All that I mention below may be an incorrect approach, so please guide me on the correct one.

My goal, is to set a percentage velocity, and have the motor run at the velocity.

My only feedback is degrees of movement, which I have correlated to an acceptable input -> output ratio. Meaning, without any resistance, if I have moved 50 degrees in 250mS that is considered 100% velocity. 25 degrees = 50% etc.

As mentioned in another thread here, I've experimented with setting waypoints for the PID controller. That is, if I were moving at 100% velocity, I set a waypoint that is 50 degrees away from the last one, every 250mS. This appears to be working fine under non problematic angles.

The problem is, if I am at a lower speed, such as the 50% velocity. There are certain angles where the proportional gain is not enough, and the motor is stuck. I've tried experimenting with how I modify the waypoints, and modifying Ki and Kp. I could enumerate them here, though I don't think it's worth it, as I think I have some fundamental misunderstanding on how to do this.

So to give an overview of my current structure in pseudo code:

while (1) 
{
    if firstRun or 250ms elapsed
        targetPosition = currentPosition + scaledVelocityValue

    if 10mS elapsed
        calculatePID()
}

In this case, the currentPosition is not be the previous targetPosition, and therefore the speed is always constant. I've tried using the previous targetPosition, but that creates an unstable system because it's such a large increase.

I hope this makes some sense. Some guidance please.

$\endgroup$
  • $\begingroup$ What is the final output of your controller? Position (I don’t think so) or voltage? Why don’t you try working in speed terms instead of working in position terms? $\endgroup$ – Gürkan Çetin Jul 6 '18 at 5:37
  • $\begingroup$ The final output is a PWM value, which is directly driving the velocity of the motor. I'm not sure what you mean by working with speed terms, can you elaborate? $\endgroup$ – Michael Jul 6 '18 at 11:57
  • 2
    $\begingroup$ Let me try: Instead of defining a new target position, you can compute the current speed, by differentiating current and previous position. {CurrentSpeed = (pos - previousPos)/deltaTime}. And your controller can use TargetSpeed and CurrentSpeed as input and DeltaVoltage as output). $\endgroup$ – Gürkan Çetin Jul 6 '18 at 14:22
  • $\begingroup$ You can look into How is PIV control performed $\endgroup$ – koverman47 Jul 6 '18 at 17:07
  • $\begingroup$ Thanks for the suggestions. I ended up trying to do as you suggested Gürkan. It turned out to be a problem that requires more hardware work to be feasible $\endgroup$ – Michael Jul 12 '18 at 19:07
1
$\begingroup$

You undertook a dead-end road. You must use a velocity setpoint instead. This way, the problem boils down to the estimation of the velocity from position feedback, which is usually quite tough since it entails to deal with a derivative of a physical thus noisy signal, yielding spikes in the outcome.

Computing the standard derivative of a signal is something a good engineer should always avoid. To get around this, one could either make the derivative more robust hardware-wise by using a very resolute encoder or resort to control techniques such as Kalman filtering (where the derivative is replaced by integration) or Savitzky–Golay filtering that instead solves a linear least-squares optimization on the fly.

Related Q&A.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.