Thursday 27 June 2019

Typically, what is the function between pulse width and angle in a servo motor?


I have a pair of Futaba S3001 servers that I am controlling with a Raspberry Pi, using the pigpio library.


To control the angles of the servos, I set the pulse width according to the formula:


pulse_width = centre + angle * multiplier

where centre is the pulse width required for 0 degrees, and the multiplier is a figure arrived at by trial and error to that represents the pulse width difference required for one degree change.


For one servo, I have arrived at:


multiplier_1 = 9.444444444444445

centre_1 = 1350

and the other:


multiplier_2 = 9.222222222222221
centre_2 = 1315

This seems to work reasonably well, at least within +/- 45 degrees.


At larger angles, I am not so sure it's still within bounds, but it's hard to tell.


My questions are:





  • Is the relationship between pulse width and angle wholly linear, as I am assuming?




  • Does the linearity break down more towards the ends of the servo's travel?




  • What sort of accuracy should I expect from a hobby servo such as this?





  • Is there a better way to arrive at the function I need?





Answer



A typical function is a polynomial with multiple terms. 3 or four terms are required to get a function that fits reasonably well.


I have established this empirically through testing multiple servos (and multiple different models).


In the graph below, the x-axis represents degrees and the y-axis represents pulse-widths. This particular example is from a Tower Pro SG90, a very cheap hobby servo, with the dots representing actual values.


However, it's fairly typical of all the devices I tested:



  • the actual results don't track the curve perfectly


  • the response of the motors becomes less sensitive towards the extremes.


There's more information about this, plus a link to the Jupyter Notebook I used to produce the graph.


pulse-widths to angles


Having said that. In most cases I tested I have found that a 10ms change in pulse-width will produce roughly one degree of movement, which provides a useful rule of thumb for many applications.


So to answer the specific questions:



  • The relationship between pulse-width and angle isn't wholly linear, though I guess it's supposed to be roughly so.

  • The linearity breaks down increasingly towards the ends of the servo's travel.

  • Micro-servos such as SG90s seem to have a resolution of (quite approximately) 1.25 degrees, but they also suffer from hysteresis (i.e. where they land can depend on which direction you're coming from). I had better results with some larger, more powerful servos (Futaba S3001) but not some others.


  • In order to arrive at the function I needed, I captured some pulse-width/angle values, as shown, and used Numpy to find the curve of best-fit.


No comments:

Post a Comment

arduino - Can I use TI's cc2541 BLE as micro controller to perform operations/ processing instead of ATmega328P AU to save cost?

I am using arduino pro mini (which contains Atmega328p AU ) along with cc2541(HM-10) to process and transfer data over BLE to smartphone. I...