# Smooth servo movement for a crawling robot

I made a small crawler robot a little while ago that had two legs with two degrees of freedom each, so 4 RC servos total. While I was programming the movement of the legs I noticed that they moved rather stiffly. It makes sense that the RC servo's internal controller would have a very quick response to position commands, but I wanted my crawler to move in a way that seems a little more smooth and life-like.

My solution was create a cubic function of time that describes the path of the servos, and then set their position in small time increments, resulting in more smooth motion. Essentially what I did was solve for the $a_i$ coefficients in a cubic equation using the time interval, starting and ending position of the servo, and starting and ending rates the servo should move (which is just the derivative of the position):

Solve for $a_0$, $a_1$, $a_2$, and $a_3$:

$$position(t) = a_0 + a_1t + a_2t^2 + a_3t^3$$ $$rate(t) = position'(t) = a_1 + 2a_2t + 3a_3t^2$$

Given: $position(0)$, $position(t_f)$, $rate(0)$, $rate(t_f)$

I set the rate of the servo between a pair of movements to be zero if the movements were in opposite directions, and positive or negative if the movements were both in the positive or negative direction, respectively.

This worked pretty well, but this solution is limited in a few ways. For one, it's difficult to decide what exactly the rates between movements that go in the same direction should be. I used the average of the slopes ahead and behind of a particular position between movements, but it isn't clear to me that is optimal. Second of all, cubic curves could take the servo to a position outside of the range of the positions at the beginning and end of a movement, which may be undesirable. For example, at some point during the time interval, the curve could cause the servo to go beyond the second position, or below the first position. Thirdly, curve generation here does not consider the maximum rate that the servo can turn, so a curve may have the servo move at a speed that is unrealistic. With that, a minor concern is that the maximum turning rate depends on the response of servo's internal controller, and may change depending on the size of the position interval.

Neglecting that last concern, these issues may be solved by increasing the degree of the polynomial and adding constraints to solve for the coefficients, but I'm now starting to wonder...

Is there a better way than this to make servo movement smooth and seem more life-like?

• The code should have been relatively straight forward. Can you talk more about why it was involved? – DaemonMaker Jul 31 '13 at 0:19
• You're right, the code was fairly straight forward, although the resulting method to control the servos was more complex than before. I have edited my question to include a description of the limitations of this method instead. – Robz Jul 31 '13 at 1:14
• NURBS, non-uniform rational B-splines, might do the job – James Waldby - jwpat7 Jul 31 '13 at 2:01
• @jwpat7 thanks for your input, but I don't think NURBS would work because those curves are not guaranteed to hit the points provided – Robz Jul 31 '13 at 9:18
• Is it as simple as lowering your $K_p$ coefficient? – Ian Jul 31 '13 at 14:50

Motion Profile Generation

In the past, I've used a motion profile generator to solve this problem. To use it you would need the desired target position (set point), maximum velocity, and acceleration values that are associated with your motors. It works by integrating a trapezoidal velocity curve in order to get a smooth position profile. An S-curve can be used if the motion has to be even smoother. Reference to article explaining Motion profiling.

Set Point Pre-filtering

Aside from the motion profiling route, you can try simply low pass filtering the command to the servos. This type of setpoint filtering will slow your response down but it will also smooth it out and it's easy to implement. The cut-off frequency will have to be chosen so that it supports the bandwidth of your system (so it does not filter out desired motion). Simple Low-pass filter implementation in C

• +1: definitely motion profile generation. – Guy Sirton Aug 1 '13 at 5:35

I think the question refers to this sort of device: RC servo

Those usually aren't very high performance so they're not going to be able to track a generated motion profile very well. Most commercial motor control systems use an S curve for a point to point move (see @ddevaz's answer) which do a piece-wise profile where each segment uses a different equation. Your problem is going to be that in order for your motor to track the generated profile you're probably going to have a very "slow" profile. Otherwise the profile you try and command the device to follow is going to have a large position error vs. the actual position of the device.

Ideally you'll want some sort of feedback you can look at while you are executing the motion so you can see how well the device is tracking the command. From a more practical perspective, if you want significantly better motion you may need different motors and different motor control.