Servo

javadoc

 

The Servo service is used to control servos through a micro-controller such as an Arduino or a Raspberry pi (ServoController).

The service will allow to control attaching or detaching the device, control his position and the speed at wich it move to that position, and turn off/on the servo.

servo.attach(controller, pin, pos, velocity): Initial servo device attachement to the microcontroller

servo.detach(controller): detach the servo from the microcontroller

servo.enable(): will turn the servo motor on

servo.disable(): will turn the servo motor off

servo.moveTo(pos): ask the servo to move to a position

servo.moveToBlocking(pos): ask the servo to move to a position and wait the position reached

servo.map(inputMin, inputMax, outputMin, outputMax): default to (0,180, 0, 180). Allow to map a range to a valid output range that can be understand by the servo. The outputMin and outputMax must have value between 0 and 180.

map

servo.setInverted(true/false): Reverse the direction of rotation of the servo.

Look at sample script bellow for others commands !


Setup

Connect the signal wire to a pin on the controller

Connect the (+) wire to the (+) of a power source (battery or power supply)

Connect the (-) wire to the ground of a power source AND the ground of the controller

Servo needs a lot of current and require to be connect to a power source that can provide enough current. The controllers (Arduino or Raspberry pi) are not strong enough to make the servo work properly and you should avoid connecting the 5V of the controller to the servo.

 

 

Speed control

servo.setVelocity(degree/s): Will force the servo to rotate at the specify velocity. If the speed specify is faster than the servo capability, the servo will turn at a lower speed than expected. The value -1 will bypass the speed control and have the servo rotate normally.

This is a common Servo service.  All simple Servos need to attach to a ServoController.  Currently, the list of ServoControllers are :

The Servo needs a controller in order to operate.  You should be able to select one in the drop down.  Select the correct signal pin the servo is attached to.  Then select "attach" and the servo should be controllable with the slider bar.  Limits can be set in order to protect the servo from going beyon a certain minimum and maximum value.

 

Modular Block Diagram showing the differences of sweeping a Servo from MyRobotLab versus sweeping it from the microcontroller (Arduino)

 

Examples:


#file : service/Servo.py edit raw
#########################################
# Servo.py
# categories: servo
# more info @: http://myrobotlab.org/service/Servo
#########################################
# uncomment for virtual hardware
# virtual = True

servoPin01 = 4
servoPin02 = 5

# port = "/dev/ttyUSB0"
port = "COM15"

# start optional virtual arduino service, used for test
if ('virtual' in globals() and virtual):
    virtualArduino = Runtime.start("virtualArduino", "VirtualArduino")
    virtualArduino.connect(port)

# create a servo controller and a servo
arduino = Runtime.start("arduino","Arduino")
servo01 = Runtime.start("servo01","Servo")
servo02 = Runtime.start("servo02","Servo")


# initialize arduino
# linux or macos -> arduino.connect("/dev/ttyUSB0")
print("connecting arduino to serial port")
arduino.connect(port)

# set limits
print("setting min max limits of servo")
# servo01.setMinMax(0, 180)
servo01.map(0, 180, 0, 180)

# set rest position
servo01.setRest(90)

# attach servo
print("attaching servo with pins to controller")
servo01.attach(arduino.getName(), servoPin01)
servo02.attach(arduino.getName(), servoPin02)

# auto disable - this enables (starts pwm) before a movement
# and disables (stops pwm) after a movement
servo01.setAutoDisable(True)
servo01.disableDelayIfVelocity=1000 # grace period for autoDisable
servo02.setAutoDisable(False)

# speed changes
print("speed changes")
servo01.setVelocity(20) ## Low velocity
servo01.moveToBlocking(90) # moveToBlocking will wait for finished move

servo01.setVelocity(50) ## medium velocity
servo01.moveToBlocking(180) # moveToBlocking will wait for finished move

servo01.setVelocity(-1.0) ## max velocity ( no more speed conytol )
servo01.moveTo(0) # we cannot use moveToBlocking if servo velocity is set to -1 ( max ) !!
sleep(2)


# fast sweep 10 seconds
print("fast sweep")
#servo01.sweep(0, 180, delay, step);
servo01.sweep(0, 180, 50, 5);
sleep(10)
servo01.stop()


# print info
print("servo position :{}".format(servo01.getPos()))
print("servo pin :{}".format(servo01.getPin()))
print("servo rest position :{}".format(servo01.getRest()))
print("servo velocity :{}".format(servo01.getVelocity()))
print("servo is inverted :{}".format(servo01.isInverted()))
print("servo min :{}".format(servo01.getMin()))
print("servo max :{}".format(servo01.getMax()))


# sync servo02 with servo01
# now servo2 will be a slave to servo01
print("syncing servo02 with servo01")
servo02.sync(servo01)

servo01.moveTo(10)
sleep(0.5)

servo01.moveTo(179)
sleep(0.5)

servo01.moveTo(10)
sleep(0.5)


# writing position in us
servo01.writeMicroseconds(1875)
print("servo position :{}".format(servo01.getPos())) # check if correct ?


# moving to rest position
print("servo01 rest")
servo01.rest()
sleep(2)

# turn off power if servo01.setAutoDisable(False)
print("turn of servos pwm")
servo01.disable()
servo02.disable()

# detaching servo01 from controller
# TODO - make arduino.detach() detach all services
print("detaching servos from controller")
servo01.detach()
servo02.detach()

MdG_NL's picture

Acceleration option for servo's

Is there a easy way to include a acceleration option in this Servo service or in a service from InMoov ?

Most servo's will start direct in full speed to move to the new position.
This gives a higher risk to burn a servo !

moz4r's picture

Hi Marteen I asked myself the

Hi Marteen I asked myself the same thing :) .

I think we can do increase speed in a thread for smoth gesture ( servo start ) 

but we don't know when the servo reach the position to descelerate. ( the only way is to read maybe the potentiometer value ? )

MdG_NL's picture

Hi Anthony,The main problem

Hi Anthony,

The main problem is the lower resolution, when we only use the 0<>180 degree step resolution in default !

For some functions it would be interesting to use the full microseconds function.

This gives more freedom to play with some settings in acceleration options.

And there is more precision because of the "5 times" higher resolution :)

2400 - 544 = 1856 microseconds

1856 / 180 = 10,3 microseconds per degree

Most servo's have a deadband from 2 microseconds, so this is the minimum stepsize.

10,3 / 2 = 5,15

I don't think we need the feedback from the potentiometers.

We only need to now how many degrees we need to make from position A to B.

If there is a option to use the "look a like" servo setSpeed function like we have in the default servo service, it would be nice.

I'm not that perfect in programming yet and Phyton is new to me...

So I don't now the limitation.