I've beee trying to get a linear actuator to rach out and poke something and then go back. I can only get it to move if I put the setTargetPosition and setEngaged in a while loop but then I can't break out of the while loop using the on target position reached handler. Here's my code:
import sys
import time
from Phidget22.Devices.RCServo import *
from Phidget22.PhidgetException import *
from Phidget22.Phidget import *
class PokeyMtr:
def __init__(self, channelId, target_position, serial_number):
self.mtr = RCServo()
self.mtr.setDeviceSerialNumber(serial_number)
self.mtr.setChannel(channelId)
self.mtr.openWaitForAttachment(1000)
self.mtr.setOnTargetPositionReachedHandler(self.targetReachedHandler())
self.targetPosition = target_position
self.isDone = False
def go_mtr_go(self):
while True:
try:
self.mtr.setTargetPosition(self.targetPosition)
except PhidgetException as e:
print(e.details)
self.mtr.setEngaged(True)
def targetReachedHandler(self):
print("yo")
pokey = PokeyMtr(0, 44.0, 305396)
pokey.go_mtr_go()
If I just have the the stuff in the go_mtr_go function outside a while loop the targetreachedhandler prints "yo" but the motor never moves. Not sure what I'm doing wrong. I'm a noob.
In "go_mtr_go(self)" it looks like you're setting the target position before engaging the device? Perhaps try setting the target after engaging? I've never used this Phidget but I think the stepper Phidgets have to be engaged first. I'm a noob too.
setTargetPosition will work regardless of whether it's called before or after setEngaged.
The problem with this code is that, without the loop, the program terminates immediately after the "yo" is printed. This does not allow enough time for the servo to reach the desired position. If you add
mparadis not sure I understand what adding the 2 second sleep does but it works. the position reached handler doesn't work like I thought it would. it gets triggered almost as soon as the motor starts moving even though the motor may move for several seconds after that. Also when I add the 2 second sleep the motor will keep moving after the program ends if it takes the motor longer than 2 seconds to move. If I move the motor form position 44.0 to 144.0 it can take more that 9 seconds. I'll have to try to find some info a bout pulse width etc. here's what I have now and it does what I want it to. I added in the currentinput device because I might going to monitor the current an use that as an indicator that I've reached desired position. ie current = 0.0
def go_mtr_go(self, target_position):
try:
self.mtr.setTargetPosition(target_position)
except PhidgetException as e:
print(e.details)
self.mtr.setEngaged(True)
sleep(2)
while True:
current = self.driver_board.getCurrent()
print(current)
if current == 0:
print("motor off")
return
Without the 2 second sleep, your program gets to the end of the code and exits immediately, as it has no more code to run.
With the 2 second sleep, the program stays alive for long enough for the Target Position Reached handler to be called before exiting.
If you don't close your Phidget properly at the end of your program, the servo controller will continue to send the motor to its last target position, as it has never been told to stop.
RC Servo controllers don't actually know the position of the servo they are controlling, they only know where they are telling the motor to go. The acceleration and velocity limits set in software adjust the trajectory of a series of positions being sent to the RC servo over time, to try to track a given motion profile.
If the motor is too slow to keep up with the set acceleration and velocity limits, the motor controller will say it has reached the target position (i.e. it is sending the signal for the final target position) long before the RC servo actually gets there.
You can adjust the velocity limit of the servo controller to something closer to the speed of your linear actuator to have the Target Position Reached event line up with the time the motor actually gets there.