# How to: implementation problem with Position control on a 3 Wheels robot (2 motorized) with velocity profile of trapezoid

I'm trying to apply position control in a wheeled robot, controlled by an arduino mega. The robot has two wheels powered by two dc motors (1 motor for each wheel) and one castor wheel. In order to implement the position control, I'm using classic PID control applied to each wheel seperately. My goal is to achieve some accuracy of moving and of course that the robot is moving in straight lines when told so (this means the wheels shall spin with the same speed, for the same distance and at the same time - otherwise the robot, would of course, turn). Following, I have gathered how I try to do this, some issues I face and some questions that I would like to ask.

The way I'm trying to achieve these robot functionalities is the following:

• the error feeded as input to the control unit is estimated by the position generated from a trajectory profile that i wish the robot to follow, minus the actual position the robot has actually travelled.

• afterwards, the output of the control is fed, in the form of pwm value, from the arduino to the motor controller, which i guess is (something similar to) an h-bridge.

• about the desired position: as mentioned i have made a trajectory generator function. This trajectory is actually the integral of a trapezoid velocity profile. The desired position (des_pos) is actually a function of the pwm value, that i send from the arduino to the motor controller board. For example, for the accelerating phase, the position is calculated from the formula: 0.5(vmax/tacc)t^2 , where tacc is the time of acceleration. and vmax is the pwm value.

• about the actual position: the encoder provides feedback of the position of the motor. This information is translated into actual (centi)meters that the robot has travelled (using the diameter of the wheel and the total number of ticks per revolution generated by the encoder)

Issues:

• the des_pos as said is a function of pwm. That means that its units are not meters. Which in principle is wrong. To make things worst, the error is computed between dissimilar quantities.. My idea was that I could either try and make some tests and map different values of pwm to the corresponding velocity of the robot. Then, by interpolation I could transform pwm values to velocity. Another option is to "absorb" this error inside the values of the gains. In other words, that during gain tuning I would be able to make this issue "hide".

• the robot in order to move in the ground, where is placed, requires a threshold pwm value. Otherwise, if less pwm value than the threshold is provided then the robot can not start moving. This is perfectly normal, since friction, dynamics of the motor etc are opposing the movement. When applying PID though, the output of the control has to be mapped to produce values of "pwm adjustment" with respect to this minimum pwm value.

Questions:

• What is the proper way to implement position control here? What is the "proper" approach in this kind of robots? My approach has many issues (see above) and it seems like gain tuning is tough.

• How can I handle the issues I mentioned or what is the best practise?

• The response I get from testing the aforementioned setup is that the motors are doing an interrupted movement. In other words, it seems like the robot alternates between 0 and minimum pwm value, instead of progressively increasing speed. Theoritically, is this a result of bad pid tuning? Or is it because of the minimum pwm value required to ignite movement in the robot?

• Something different, but more general let's say, regarding control theory. My understanding is that velocity and position control are actually different sides of the same coin. If I am not mistaken, the main difference has to do with the feature (velocity or position) which we pay attention in [for example in position control, you can manage the same result with velocity control - meaning you reach the same distance - but you have overshooting and all aspects of control focused on position whereas in velocity control you have focused on velocity], as mentioned also here. Also, what is the case when you need to take into account the dynamics of the motor? Or in other words, when is it necessary to insert the dynamics of the motor inside the control scheme?

Thanks in advance and sorry for the long post. I m looking forward to any help!

• Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer.
– Community Bot
Dec 14, 2022 at 15:21

This is a long post that's a bit all over the place, but as concisely as I can:

You say,

Issues: the des_pos as said is a function of pwm. That means that its units are not meters

but you also say,

about the desired position: as mentioned i have made a trajectory generator function. This trajectory is actually the integral of a trapezoid velocity profile.

This doesn't make sense to me - if you have a desired position, then that should determine the velocity trapezoid. If you have a velocity trapezoid driving the desired position, then you don't really have a desired position, you have a desired velocity and whatever position you get from that is incidental.

Regardless, you go on to state:

the position is calculated from the formula: 0.5(vmax/tacc)t^2 , where tacc is the time of acceleration. and vmax is the pwm value

If you want engineering units, you should have vmax as a real speed, which means you need to calculate motor top speed, gearbox ratio, wheel diameter, etc.

The rest of your questions all seem to revolve around issues with PWM control, so I'll put it like this: Your vehicle controller (as described) should generate a trapezoidal speed profile, in some kind of engineering unity like meters per second.

You can use a PID controller at each wheel that accepts the trapezoidal speed control as an input. You can calculate wheel speed with wheel radius, gearbox ratio, and motor speed. The wheel speed error is reference (input) minus feedback (calculated). The wheel speed error is what you pass to the PID controller; P term acts directly on that error, take the integral of the error for the I term, take the derivative of the error for the D term. Take those outputs, (kPerror) + (kIerror_integral) + (kD*error_derivative), and send that out as the PWM signal. Any scaling that needs to happen for PWM will be taken into account when you do your tuning.

I would also highly recommend using a feed-forward term in your controller. This will take a bit of study on your part, but pay attention while you're doing your tuning and you should be able to plot PWM signal against steady-state wheel speed. The feed-forward "controller" will use this curve to send the estimated PWM signal to the motor directly, and the PID controller then only has to act to make up for dynamics and disturbances. I guarantee you'll get significantly better performance with feed-forward control than with pure PID, because PID can only ever act on an error - PID controllers won't send anything until you're failing to match the reference input.

• Thanks for your reply. Regarding the des_pos: The code expects the user to feed the robot with some des_pos which the robot shall travel. Based on this, I pass traj.generator parameters in order to achieve this. When the velocity profile is integrated, a s-curve type profile is created, which is the position over time. The position after t_final - that is the total time to elapse for the speed to become again 0 - must have reached the desired position. Since my goal is that the robot reaches the desired position, it feels to me better to feed the pid with position and not velocity. Dec 15, 2022 at 16:23
• From your answer I understand that both in position and velocity control (that you described), the control output's unit - which I consider a problematic issue - is handled by the tuning of the gain (this is what i understand from what you refer to as scaling). Alright, this seems fair but that also makes tuning a little bit difficult in my opinion. Dec 15, 2022 at 16:24
• Regarding PWM issues: The ignition of the movement still troubles me. Maybe you have some comment about it? As said in the original post, this issue is normal - and should be expected - but in the practical world, it gives me trouble. Maybe I need more testing with the robot and then come back. Right now all I am doing to overcome this is to map (with interpolation) the control output result into some value with specific limits. Shall I try something different? Dec 15, 2022 at 16:25
• Regarding the feed forward control: If you can shed a little bit more light here, I would appreciate it. The idea is that i must have a plot of PWM-speed curve which will feed the feed-forward control (as well as in the classic PID control). The classic PID remains the same and in its output I add (or multiply?) estimation of the PWM? This estimation is based on what? Also, can this be utilized in position control as well? Certainly, I need to study more feed-forward control, but any simple explanation is appreciated. Dec 15, 2022 at 16:25
• Generally speaking, shall I expect that this scheme of control is going to be effective or not? I mean is this some approach other engineers follow? Lastly, I would like to ask if you agree with the following: It seems to me that it is not a good practice to avoid making this PWM-speed curve and trying to "fix" everything with the tuning of the gains. Thanks in advance - I truly appreciate your feedback - and sorry for the trouble. Dec 15, 2022 at 16:26

The desired position (des_pos) is actually a function of the pwm value, that i send from the arduino to the motor controller board.

As you've described it, the output of the PID loop is not desired position, but rather something akin to torque. It's not exactly torque since you would need to measure current to get torque. It's not exactly velocity either since your profiler works on position. But PID out most certainly is not desired position. Desired position comes from the profiler. The PID is generating the 'effort' the motor puts into minimizing position error.

In any case, I see nothing wrong with your approach. It will not provide you with very high performance but should be effective. I have had projects that worked well using the same simple approach you're discussing.

NOTE: before someone points out that having your error generated against position profile sould be considered velocity since the same math is getting done but just in different places...I agree in advance. There is a fine line and it could be considered velocity, even though the velocity went into generating the profile instead of coming out of it.