Angle curve tuning - position control

What do you mean by real life example? I would give you a real life analogy: The PID is like a cab driver, and you are to tell the him to drive a taxi to your set-point position. Now the problem with this particular cab driver is that he doesn’t care about the car he is driving or how his driving behavior turns out to be when he hits the gas pedal. All he cares about is how far away he is from the current position to the target position you told him. He does not care about safety, car’s horse power, law of physics, passengers’ comfort. If he’s in Barcelona and you tell him to drive to Oslo, he will floor the sht out of that gas pedal and hold it like that until the cab eventually reaches its destination. And upon reaching that exact target spot, the driver will slam the sht out of the brake pedal. Basically, that’s what a PID controller do. Tuning the parameters is just adjusting the intensity of pedal slamming. The behavior in general will not change as much.

I didn’t take any courses in control theory, but I believe setting an instant target is referred to as “Step Target”, and what the PID controller attempts to do with that target is to generate a “Step Response”, meaning that it tries as hard as possible to reach that target instantly. From the analogy above, it’s like teleporting across Europe in less than a second, which in reality is not possible.

So when you think about setting target position to the motor, it’s very similar. If you tell it to go 180 degrees forward, it might go very smoothly, because the distance is not large, the driver is not flooring the pedals. But if you tell it to go say 720 degrees (2revs) immediately, you might see something like in your video, where the motor jerks a lot at first (because error now is very large), then as the error lessen, it slows down. That’s the behavior of the motor under the effect of the PID controller, which the controller itself doesn’t care about.

So, by using a function to generate target position, it’s like you continuously telling the cab driver to drive by 100 meters every few seconds until the destination. The motor.move(…) function is doing exactly that. In some BLDC servo applications, it is referred to as “Cyclic Synchronous” mode. Here, have a look at a German Brushless driver’s manual: Circulo Driver, page 606 of the PDF file, Modes of Operation.

For motion profile, you can implement a simple 1st order linear ramp of target, something like:

// Your other code ...

float generateTargetRamp(float currentPosition, float targetPosition, uint32_t *millisecondNow)
{
    // Use linear interpolation to solve for f(t) = a.t + b
    float outputTarget = a * (*millisecondNow) + b;
    return outoutTarget;
}

void loop()
{
    timeNow_ms = millis() - timeStart_ms;
    // Go from current angle to 7200 degrees:
    float targetDeg = generateTargetRamp(motor.shaftAngle(), 7200.0f, &timeNow_ms);
    float targetRad = // Convert deg to rad, I believe the library sets position as radians
    motor.move(targetRad);
    motor.loopFOC();
}

Regarding the noise in velocity reading, it looks fine to me, that’s not really your problem. SimpleFOC does have a LowpassFilter for velocity. If you love having it smooth, try cranking up the filter.

About this, I no longer use SimpleFOC so I don’t have any code other than what suggested above to share, sorry. I just love the community, and my FOC journey started from this very lovely library.