GithubHelp home page GithubHelp logo

frc4564 / maestro Goto Github PK

View Code? Open in Web Editor NEW
93.0 93.0 59.0 109 KB

Python class to support Pololu's Maestro servo controller over USB serial. Great with Raspberry Pi.

License: MIT License

Python 100.00%
control-servos maestro pololu python raspberry-pi

maestro's People

Contributors

frc4564 avatar pdg137 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

maestro's Issues

Multiple Maestros

It might be worth noting in the documentation and/or code that this is also a way of identifying a Maestro:

self.servoControllerA = maestro.Controller("/dev/serial/by-id/usb-Pololu_Corporation_Pololu_Micro_Maestro_6-Servo_Controller_XXXXXXXX-if00")

Where XXXXXXXX is the ID of the Maestro.

If you use the /dev/ttyA*** method, they may change depending on the order in which devices are attached or powered up. The soft link provided by /dev/serial/by-id will always attach to the the same controller.

(PS thanks for the code!)

documentation needs more detail for beginners

I'm completely new to the Maestro hardware and software, and I had some trouble making it work on Windows with Python.

I made some changes to the README to guide complete newbies like me:

#9

Thanks!

Issues controlling multiple servo at same time

hey,
I tested your library and its a good job done by you
but your code has some issues
it works for only one servo at a time
let me explain
first it gives error saying it needs to be encoded to bytes, unicode not supported
so we should simply edit it to cmd.encode()
this solves the problem in python shell

but if you try to send command for 2 servos like this

maestro.setTarget(0,6000)
maestro.setTarget(1,6000)

maestro will always understand the second command
and the servo1 will reach to position to 6000 and hold the position
and servo 0 will not go anywhere also you can freely rotate servo 0 with your hands
this concludes that there is some error in sending bytes to maestro which will always light up red led

i have also posted this issue on pololu forum
https://forum.pololu.com/t/controlling-two-servos-at-same-time-problem/12282

Today i figured out the problem
using .encode() solves the problem from python side but it also adds up an extra byte '/xc2'
this creates error in maestro servo controller
suppose you want to give command like this

maestro.setTarget(0,6000)
maestro.setTarget(1,6000)

this sends bytes like
'\xc2\xaa\0xc\0x04\channelbyte 0\byte lsb0\byte msb0 \xc2 \xaa\0xc\0x04\channelbyte1\byte lsb1\byte msb1'
if i am not wrong
this means maestro detects wrong command
\xc2\xaa\0xc\0x04\channelbyte 0\byte lsb0\byte msb0 \xc2' upto here
and next command '\xaa\0xc\0x04\channelbyte1\byte lsb1\byte msb1' gets valid
this ends up controlling only servo 1
also lights up red led on maestro indicating unknown command error

so i have to again modify the code like this

import serial
ser=serial.Serial('COM10',115200,timeout=1)

def setTarget(chan, target):
           
        lsb = target & 0x7f #7 bits for least significant byte
        msb = (target >> 7) & 0x7f #shift 7 and take next 7 bits for msb
        # Send Pololu intro, device number, command, channel, and target lsb/msb
        cmd = (chr(0xaa) + chr(0xc) + chr(0x04) + chr(chan) + chr(lsb) + chr(msb)).encode()
        command = cmd.split(b'\xc2',1)
        ser.write(command[1])
i=9000
setTarget(0, i)
setTarget(1, i)

which will split the bytes by \xc2 and will send the exact required command
this finally solves all the problem and all the servo reaches correct position also no red error led

hope You will understand this long issue
and modify the library
so that our python guys gets no issues
maybe the issue was because i am coding on my pc using python
and will not cause any problem on RPi

Reading serial input

So there is a sendcmd in the code, in case I need to read a designated serial input (like a sensor input), is there a way to do it? thanks in advance.

p.s sorry, I tried to put this topic in the question category and somehow it popped up here.

Any way to code a sequence?

I'm trying to utilize this to code a sequence, but it seems to only go to the last position. Is there any way to do this? Here's my attempt:

import time

MIN_S = 0
MIN_G = 0
CENTER_S = 6000
CENTER_G = 6000
MAX_S = 12000
MAX_G = 12000

class RubikSolve:

    # Pass the maestro controller object and the maestro channel numbers being used
    # for the left and right motor controllers.  See maestro.py on how to instantiate maestro.
    def __init__(self, maestro, rightSlider, rightGripper):
        self.maestro = maestro
        self.rightSlider = rightSlider
        self.rightGripper = rightGripper
        # Init motor accel/speed params
        self.maestro.setAccel(rightSlider,0)
        self.maestro.setAccel(rightGripper,0)
        self.maestro.setSpeed(rightSlider, 0)
        self.maestro.setSpeed(rightGripper, 110)
        # Motor min/center/max values
        self.minS = MIN_S
        self.minG = MIN_G
        self.centerS = CENTER_S
        self.centerG = CENTER_G
        self.maxS = MAX_S
        self.maxG = MAX_G
        
    def servoMove(self, servo, position):
        self.maestro.setTarget(servo, position)
        
    # Right
    def R_clock(self):
        self.servoMove(self.rightSlider, self.minS)
        print('rightSlider')
        time.sleep(1)
        self.servoMove(self.rightGripper, self.minG)
        print('rightGripper')
        time.sleep(1)
        self.servoMove(self.rightSlider, self.maxS)
        print('rightSlider')
        time.sleep(1)
        self.servoMove(self.rightGripper, self.maxG)
        print('rightGripper')

Then once that's defined I run this:

import maestro
m = maestro.Controller()
rs = RubikSolve(m, 0, 1) #maestro channels 0 and 1 for left and right motors

for i in range(1):
    rs.R_clock()

m.close()

Am I missing something simple here?

No License

Can you add a license file or explicit notice in the source code for others who wish to use the module?

No response with Maestro 24 on Linux

Should this code work with the Maestro 24? Pololu's docs all state each channel needs to be enabled before using and that once enabled the yellow LED should flash twice, but I don't see anything in your code that enables the channel before use.

Also, I believe most pins on the Maestros also double as a true analog input, but there doesn't appear to be an interface for this in your class. Is this possible?

How do you to turn off and on (disable/enable) a channel that is stuck in a feedback loop?

Hi,

I have a question about what I can best do when the servo is stuck in a feedback loop. When I set a target for the servo channel, it sometimes happens that the target it not fully reached and the servo keeps trying to get to the indicated position. This has happened for different target values. Unfortunately, I cannot tell it to stop the PWM sending, as only one of the channels has that option, and I plan on using two channels. I tried to fix it with this code, by simply restating the target when getting close to it, but it doesn't always solve the problem:

if abs(servo.getPosition(0) - target) < 5.:
    servo.setTarget(0, servo.getPosition(0))
    servo.close()

Even when you close the servo, the servo keeps working and you have to disable it manualy in the Maestro Control Center. Besides, you'd rather not have to fully close and reconnect the servo after each target statement, but rather only temporarily the channel that is experiencing issues. It's just that I don't know how best to define the rapid back-and-forth positions when it's stuck, since you don't have an iterative overview of all positions as the target it set.

I've tried using the fact that it's moving as a control condition, but while jammed/stuck in the loop it claimes it's not moving, even though you can hear it vibrating and working. This makes it difficult for me to pinpoint a solution, other than "keep the Maestro Control Center at hand in case of emergency".

In the Maestro Control Center I've also experienced this same problem, but there I could avoid damage to the servo controller by manually disabling the respective channel. Is there a way to also do this through python? Or are there other suggestions?
Are the settings like speed and acceleration relevant for this? I tend to use v=10 and a=5, but have this problem for different values as well.

Thanks!
Vera

Port to circuit python for adafruit controllers

Can the Maestro PY class be configured to work for circuit python? This would be a fantastic combination to be able to use the maestro servo controller with the adafruit feather microcontroller using circuit python.

How do you immediately stop a servo's movement?

I am using the Maestro controller to control animatronics for Halloween and Christmas displays. I had a problem where the display got stuck and the servo kept trying to move it. This is real bad for the servo.

I can detect that the servo did not reach its commanded position, but I cannot figure out how to stop it immediately.

I appreciate any ideas. Thanks,

Paul

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.