Fine Servo Control With Joystick

 

 

 

What do we want !  That's right MORE CONTROL !!!  In this short tutorial I will show you how to get fine and relatively smooth control using the Joystick and Servo services.

Mech-Dickel wanted to use the joystick of a game pad to control the direction and use a button key to start and stop.  In this example we are going to control the Y axis of a pan / tilt kit, and use the (1) button for on / off.

Hardware

I am using  a wireless Logitech rumble pad 2, a BBB Arduino, and a generic servo.

Software

I have loaded the latest MRLComm.ino into the Arduino and will be using the following MyRobotLab Services:

Rather than MRL (MyRobotLab) sending individual incremental position commands to the servo on where to go, we will tell the servo to move at an incremental speed.  When the servo is moving at an incremental speed (<1.0) we have the ability to tell the servo to stop.  If we had sent a command to the servo from Python for each position the 57600bps serial speed and the computer's scheduler can make the movement very jittery.  Telling the Arduino to start moving and when its moved to the correct position, commanding it to stop is much more effecient and smooth.

Python


#file : toSort/Joystick.Servo.fine.control.py edit raw
# system specific variables
port = "COM12"
servoPin = 6
joystickIndex = 7
# set servo speed 
# if you are going to do "stops" on a servo
# it MUST have speed < 1.0
servoSpeed = 0.7

# globals
servoDirection = 0
# max and min of servos - use to limit the movement
servoMin = 0
servoMax = 180

joystick = Runtime.createAndStart("joystick", "Joystick")
arduino = Runtime.createAndStart("arduino", "Arduino")
servo = Runtime.createAndStart("servo", "Servo")

if (not joystick.isPolling()):
	joystick.setController(joystickIndex)
	joystick.startPolling()

if (not arduino.isConnected()):
	print "connecting arduino"
	arduino.connect(port)
	print "attaching servo"
  servo.attach(arduino.getName(), servoPin)
	# add the python service as a listener to the joystick event YAxisRaw
	joystick.addListener("YAxisRaw", python.name, "y")
	# add the ptyon service as a listener to the joystick event buttons
	joystick.addListener("button1", python.name, "button1")
	joystick.addListener("button5", python.name, "button5")
	joystick.addListener("button7", python.name, "button7")

servo.setSpeed(servoSpeed)

# servo direction 
# joystick all the way down = down
# joystick all the way up = up
# joystick <> up || down = no direction
def y():
	global servoDirection
	servoDirection = msg_joystick_YAxisRaw.data[0]
	if (servoDirection == 1):
		print "servo down"
	elif (servoDirection == -1):
		print "servo up"
	else:
		servoDirection = 0
		print "servo no movement"

# servo move / stop
# click = move
# release = stop
def button1():
	global servoDirection
	global servoMin
	global servoMax
	# API is now sissy 1 based for those who don't know how to deal with 0 index :)
	button1 = msg_joystick_button1.data[0]
	if (button1 == 1):
		print "servo will move"
		if (servoDirection == 1):
			print 'down'
			servo.moveTo(servoMin)
		elif (servoDirection == -1):
			servo.moveTo(servoMax)
			print 'up'
		else:
			print 'no direction'
	else:
		servo.stopServo()
		print 'is not moving'

# increase speed 5%
def button5():
	button5 = msg_joystick_button5.data[0]
	if (button5 == 1):
		# only care about pressed
		global servoSpeed
		servoSpeed += 0.05
		if (servoSpeed > 0.95): # we don't want to go to 1.0
			servoSpeed = 0.95
		servo.setSpeed(servoSpeed)
		print "speed is now ", servoSpeed

# decrease speed 5%
def button7():
	button7 = msg_joystick_button7.data[0]
	# only care about pressed
	if (button7 == 1):
		global servoSpeed
		servoSpeed -= 0.05
		if (servoSpeed < 0.05):
			servoSpeed = 0.05
		servo.setSpeed(servoSpeed)
		print "speed is now ", servoSpeed

 

GroG's picture

Darek asked - where can I find my Joystick Index

You can start a Joystick service and look what gets populated in the dropdown.  Every system is different. In my case the rumble pad registers as device 7 - so I can use the 7 programmatically.

Mech-Dickel's picture

Well done!

Hi GroG! Well done work, man! I haven't tried it yet on my project. Now we have all the control on our hands!

kmcgerald's picture

Minimum Speed

I know this is just a tutorial for others to learn from and not use exactly but I would suggest that the minimum speed be set to 0.05 or something above 0.0 because a user might get confused when pushing the 1 button and a direction does nothing because they don't realize they mashed the 7 button too much.

GroG's picture

Agreed, Changed,

Agreed, Changed, Updated

also, I didn't like the filename - I'm trying to standardize these in some form.  They are supposed to start with the "dominant" service.. this was named Python.... but on consideration "Python" is mostly glue to make all the services work together happily. (Also, to implement your suggested change I looked in the repo first for Joystick and couldn't find it ;)  filename updated too

FrankOnorati's picture

A heartfelt thanks to Grog

A heartfelt thanks to Grog for MRL and a good morning to you all. 
I just installed and started trying MRL with the following configuration: 
MRL, 
1 Arduino Uno R3, 
Logitech Force 3D Pro Joystick 1, 
1 Servo Hitec HS-5585MH (Programmable Digital Amplifier whit MOSFET Drive 
and this python sketch:
 
from org.myrobotlab.service import Arduino
from org.myrobotlab.service import Servo
from org.myrobotlab.service import Joystick
from org.myrobotlab.service import Runtime
from time import sleep
# create the services
arduino = Runtime.createAndStart("arduino","Arduino")
pan = Runtime.createAndStart("pan","Servo")
joystick = Runtime.createAndStart("joystick","Joystick")
arduino.connect("COM6", 57600, 8, 1, 0)
sleep(2)
# attach servos to Arduino
pan.attach(arduino.getName(), 9)
# attach joystick to servos
joystick.attach(pan, Joystick.Z_AXIS)
joystick.setController(5);
joystick.startPolling();
 
After starting the sketch, the joystick is detected in the window controller, if I move the slider in the "servo window" the servo moves, but the servo does not move if i want to drive it with the joystick, what am I wrong? Thanks for the reply! Have a nice day! :)