I am trying to code up a closed loop control system on force generated by the paring of strong rare earth magnets. I do not have much experience with PID logic but i have a weak grasp of the basics (ie controlling temp or something).

I am confused by the situation I find myself in below because I need to control through the positioning of the magnet. My positioning system is worm gear motor which will have a oscillating force wave-shape, which is by design since I want cyclical loading. The problem is I think this makes control way more difficult. I already have an issue in that the relationship between force and position is not linear. I think that can be managed, What I am concerned about is programing the controller to deal with the fact that if the motor goes far enough the force will not go up but down.

Ideally I would like to moderate the speed so that I could produce any sort of force(time) profile I want, without the motor going forward and reverse at all. Just accelerate/de-accelerate in one direction as necessary to fit the input curve during each revolution.

I have this set up on the beaglebone black with a PRU running the loop control. I chose this because the PRU has 5ns instruction processing times so it should be very quick the react to changes. I have a load cell digitizer capable 460800 baud rate which will be my limiting factor in processing the signals.

My first order of business is dealing with the the motor turning in one direction will both raise and lower the force depending on position. How do I cope with that? and then how do I deal with the non-linear relationship between force and magnet position.

Any advice would be much appreciated. enter image description here UPDATE

So I realized that having a stepper motor would make my life a lot easier but I want to see this through to the end...

\$Force =f(\theta) \;\;\;\ empirical \;relation \$

\$\theta = \int \dot{\theta}dt \;\;\;\ \$

\$\dot{\theta} = f(Voltage) \;\;\;\ empirical \;relation \$

I plan to handle this by modeling these functions empirically. I feel to finish my system I need some means of converting angular speed to a angle position. Now I have an integration relation which would connect these two empirical black boxes.

In terms of knowledge of the state of the system I will always know the angle position, force and voltage at all times. I can only regulate the speed. I plan to achieve my Force(time) trace by speeding up and slowing down. I will also ensure I can achieve the max force before running.

How can I control this system with these empirical relations?

some sample wave forms for reference... enter image description here

  • 1
    \$\begingroup\$ You're aware that if you have the moving magnet cycle through its whole range you'll have no control over the force at the endpoints of the travel, yes? \$\endgroup\$
    – TimWescott
    Commented Sep 22, 2020 at 14:41
  • \$\begingroup\$ @TimWescott yes I am aware of the endpoints being out of my control. I want to control the shape of the loading as the magnet travels through its range of motion. The distance/ magnet stregth is wide enough that my low is always zero. My max is modulated by the position of the plate. \$\endgroup\$ Commented Sep 22, 2020 at 15:31
  • \$\begingroup\$ @AJN 1)the force is controlled by magnet position: the moving magnet is positioned by the motor and a stationary magnet that can be repositioned manually control the max force. 2) ideally yes because I would like the motion repeated 1000s of times per use. But the motor can go in both directions if need be, but I worry about it wearing out faster. 3) I want the max force to be the same but play with loading rates, linear, sinesoidal., impulse like ..4) will post a few examples of profiles I would like to create \$\endgroup\$ Commented Sep 22, 2020 at 15:50
  • \$\begingroup\$ @AJN Sorry for the long delay. I have updated my post. I have created some empirical relations but I still am not sure how to connect voltage input to a force output. \$\endgroup\$ Commented Feb 22, 2022 at 0:15
  • \$\begingroup\$ @AJN thanks for the comment. I concede that is will need to turn around to achieve the middle wave form. I am confused about your suggestion. How do I implement the PID on the motor when the input is voltage and an output of angular velocity? Also when I say empirical formula it really is a Fourier series representation. Would that still work? If you put an answer in I can up vote it. Thank you for your assistance. \$\endgroup\$ Commented Feb 22, 2022 at 3:38

1 Answer 1


This answer is going to be rather abstract.

Let the direction your magnet travels be the x direction.

You have one known or knowable function from the position of the magnet to the force exerted. So let \$F = f_{pf}(x)\$. This function is monotonically increasing with \$x\$, which makes things easy.

You can calculate the position of the moving magnet with respect to the crank angle. Let \$x = f_{a p}(\theta)\$. Note that -- as discussed -- this is periodic on \$\theta\ \mathrm{mod}\ 2\pi\$ (and roughly, but not exactly, sinusoidal). It's also going to be continuous. This means that \$x\$ is constrained such that \$x \in [x_{min}, x_{max}]\$. Working backwards, it means that \$F\$ is also constrained: \$F \in [F_{min}, F_{max}]\$.

This means that \$F = f_{pf}\left (f_{ap}(\theta) \right)\$

You want the force to be some periodic -- and presumably continuous -- function of time, and you're willing to live with the constraints on \$F\$.

So -- easy peasy. Define your desired \$F(t)\$. For any value of \$F\$ in the interval \$[F_{min}, F_{max}]\$ there exists not one, but two values of \$\theta\$ that give you that force. So if you're at \$F_1, \theta_1\$ and you want to go to \$F_2\$, solve \$F_2 = f_{pf}\left (f_{ap}(\theta_2) \right)\$ for the two possible values of \$\theta_2\$ and choose the one that you'll get to first.

For a predetermined force vs. time relationship, solve \$F = f_{pf}\left (f_{ap}(\theta) \right)\$ for as many points as you need to get the precision you want for \$F(t)\$, making sure that \$\theta(t)\$ goes in a circle. Then control your motor with a PID controller to make it follow your predetermined \$\theta(t)\$.

  • \$\begingroup\$ I sort of get you. My problem is I am driving the crank with a DC motor so hard for me to hit a giving position. I was planning on controlling the duty cycle on the voltage and just modulate the speed in which i move from F_min to F_max. I guess my main concern is overshoot. If I over shoot too close to the max it goes down and the PID would have to flip positioning. I guess I could try just doing the controller part with just P ? \$\endgroup\$ Commented Sep 23, 2020 at 3:56
  • \$\begingroup\$ I was assuming that you knew the crank position, and that the necessary bandwidth would be moderate. Could you edit your question with the necessary cycle time, and an example force vs. time plot? You can always impose the condition on your driver that the motor never reverses. \$\endgroup\$
    – TimWescott
    Commented Sep 23, 2020 at 13:47
  • \$\begingroup\$ Sorry for the long delay I added some force vs time plots. I have also added more detail to my post. I am looking for a way to bridge rotation speed and angle position. \$\endgroup\$ Commented Feb 22, 2022 at 0:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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