Trying to control linear actuator - won't move unless it's in a while loop

Supporting 2.7 and 3.2+
Post Reply
johnsayeau
Fresh meat
Posts: 3
Joined: Tue Apr 16, 2019 8:37 pm
Contact:

Trying to control linear actuator - won't move unless it's in a while loop

Post by johnsayeau »

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:

Code: Select all

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.
hlaps1990
Phidgetsian
Posts: 5
Joined: Sat Jun 04, 2016 1:17 pm
Contact:

Re: Trying to control linear actuator - won't move unless it's in a while loop

Post by hlaps1990 »

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.
User avatar
mparadis
Site Admin
Posts: 660
Joined: Fri Oct 28, 2011 12:17 pm
Contact:

Re: Trying to control linear actuator - won't move unless it's in a while loop

Post by mparadis »

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

Code: Select all

time.sleep(2)
at the very bottom of this program, it will wait long enough for the motor to reach position before the program terminates.
johnsayeau
Fresh meat
Posts: 3
Joined: Tue Apr 16, 2019 8:37 pm
Contact:

Re: Trying to control linear actuator - won't move unless it's in a while loop

Post by johnsayeau »

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

Code: Select all

import sys
import time
from Phidget22.Devices.RCServo import *
from Phidget22.Devices.CurrentInput import *
from Phidget22.PhidgetException import *
from Phidget22.Phidget import *
from Phidget22.Net import *
from time import sleep


class PokeyMtr:
    def __init__(self, channelId, serial_number):
        self.mtr = RCServo()
        self.driver_board = CurrentInput()
        self.driver_board.setDeviceSerialNumber(serial_number)
        self.driver_board.setChannel(0)
        self.driver_board.openWaitForAttachment(1000)
        self.mtr.setDeviceSerialNumber(serial_number)
        self.mtr.setChannel(channelId)
        self.mtr.openWaitForAttachment(1000)
        self.mtr.setMinPosition(0)
        self.mtr.setOnTargetPositionReachedHandler(self.targetReachedHandler())
        self.isDone = False


    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(1)



    def close_mtr(self):
        self.mtr.close()


pokey = PokeyMtr(0, 305396)
pokey.go_mtr_go(44)
pokey.close_mtr()

I did this to prevent the go_mtr_go() from returning before the mtr is done moving:

Code: Select all

    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
jdecoux
Labview Developer
Posts: 180
Joined: Mon Nov 13, 2017 10:20 am
Contact:

Re: Trying to control linear actuator - won't move unless it's in a while loop

Post by jdecoux »

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.
Post Reply

Who is online

Users browsing this forum: No registered users and 0 guests