Skip to content

Instantly share code, notes, and snippets.

@pablobm
Last active August 20, 2017 13:21
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save pablobm/6928aa5565888ae865ce97b35e3824c1 to your computer and use it in GitHub Desktop.
Phidgets, event-driven

Notes on programming the Phidgets-powered robotic arms

General description and links

The arm is powered by a Phidgets Advanced Servo 8-motor controller. See https://www.phidgets.com/?tier=3&catid=21&pcid=18&prodid=56 Comes with a USB cable (to connect to the computer) and a power supply that uses 4 AA batteries.

To see the API reference:

  1. Visit https://www.phidgets.com/?view=api
  2. Select Python > 1061_1 (or I think just RCServo is fine)
  3. All the methods and descriptions will appear listed underneath

Other documentation:

My experiences

Channels/joints

The 4 joints are controller by 4 different servos. Each one is controlled via a "channel":

  • Channel 0: base (left/right rotation)
  • Channel 1: forearm (through a lever)
  • Channel 2: arm
  • Channel 3: claw (open/close)

This is for the blue arm. Can't be sure right now if channels 1/2 are swapped in the red arm.

Due to the way the mechanisms are connected, arm and forearm must move together in order to move effectively. This is because their parts interfere with each other physically. In other words: extension/retraction of the arm must involve moving 1 and 2 together.

To send commands to a servo or the other, use the setChannel method.

Control styles

Two ways to control the arm:

  • Imperative, polling-based style
  • Event-drive style

I found that the event-driven style was more reliable.

My experience with the feedback wasn't good. If I blocked the movement of the arm, it could think that it had reached its target anyway, and report a wrong position when calling getPosition().

Range of rotation

The base definitely seems to move betwen 0 and 180 degrees, with 90 degrees being the position where the arm faces forward.

I'm not clear as to whether the other servos are similarly calibrated. This forum link seems to suggest otherwise: https://www.phidgets.com/phorum/viewtopic.php?t=3088 Some more research is needed.

A working example

This links to a current, work-in-progress script that should work: https://gist.github.com/pablobm/6928aa5565888ae865ce97b35e3824c1 It takes a channel and a list of positions (in degrees), and sends commands to move the selected joint (channel) to the given positions.

import time
from Phidget22.Devices.RCServo import RCServo
class EventDrivenController:
def __init__(self, channelId, waypoints):
self.channelId = channelId
self.waypoints = waypoints
self.isDone = len(self.waypoints) == 0
self.servo = self._initServo()
def _initServo(self):
s = RCServo()
s.setChannel(self.channelId)
s.openWaitForAttachment(5000)
print(s.getPosition())
s.setOnPositionChangeHandler(self.positionChangeHandler)
s.setOnTargetPositionReachedHandler(self.targetPositionReachedHandler)
s.setOnVelocityChangeHandler(self.velocityChangeHandler)
s.setVelocityLimit(90)
s.setTargetPosition(self.waypoints.pop(0))
s.setEngaged(True)
return s
def targetPositionReachedHandler(self, device, position):
print ["target reached", device, position]
if len(self.waypoints) > 0:
nextPosition = self.waypoints.pop(0)
print("Next position:", nextPosition)
self.servo.setTargetPosition(nextPosition)
else:
self.isDone = True
def positionChangeHandler(self, device, position):
print ["position changed", device, position]
def velocityChangeHandler(self, device, velocity):
print ["velocity changed", device, velocity]
ctrl = EventDrivenController(0, [90, 0, 180, 90])
while not ctrl.isDone:
time.sleep(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment