pydobot icon indicating copy to clipboard operation
pydobot copied to clipboard

Dobot's inputs/outputs (request)

Open SForney54 opened this issue 5 years ago • 14 comments

Would love to have this Python library with capable of controlling the Dobot's inputs/outputs. Such as controlling the Dobot's linear rail, Conveyor Belt, 3D printing, photoelectric switches, color sensors, and etc.

Thanks, Steven

SForney54 avatar Dec 20 '19 18:12 SForney54

If i have a moment I'll write a pull request for this...

This is the code required for the photoelectric switch

PORT_GP1 = 0x00
PORT_GP2 = 0x01
PORT_GP4 = 0x02
PORT_GP5 = 0x03
    def set_ir(self, enable=True, port=PORT_GP4):
        msg = Message()
        msg.id = 138
        msg.ctrl = 0x02
        msg.params = bytearray([])
        msg.params.extend(bytearray([int(enable)]))
        msg.params.extend(bytearray([port]))
        return self._extract_cmd_index(self._send_command(msg))

    def get_ir(self, port=PORT_GP4):
        msg = Message()
        msg.id = 138
        msg.ctrl = 0x00
        msg.params = bytearray([])
        msg.params.extend(bytearray([port]))
        response = self._send_command(msg)
        state = struct.unpack_from('?', response.params, 0)[0]
        return state

Important note: Their protocol guide seems to be out of date? I had to look at the c++ sourcecode for the DobotDLL

rpeach-sag avatar Mar 06 '20 15:03 rpeach-sag

Color sensor:

    def set_color(self, enable=True, port=PORT_GP2):
        msg = Message()
        msg.id = 137
        msg.ctrl = 0x03
        msg.params = bytearray([])
        msg.params.extend(bytearray([int(enable)]))
        msg.params.extend(bytearray([port]))
        return self._extract_cmd_index(self._send_command(msg))

    def get_color(self, port=PORT_GP2):
        msg = Message()
        msg.id = 137
        msg.ctrl = 0x00
        msg.params = bytearray([])
        msg.params.extend(bytearray([port]))
        response = self._send_command(msg)
        r = struct.unpack_from('?', response.params, 0)[0]
        g = struct.unpack_from('?', response.params, 1)[0]
        b = struct.unpack_from('?', response.params, 2)[0]
        return [r, g, b]

rpeach-sag avatar Mar 06 '20 21:03 rpeach-sag

Hello, I'll test them by Monday. If you able to figure out the last three things (Sliding Rail, Conveyor belt and 3D print) before Monday would be great because I can test them and get back to you soon.

Thanks

SForney54 avatar Mar 06 '20 21:03 SForney54

The library already covers the conveyor belt but this is the code I'm using to get a more accurate distance in mm and speed in mm/second:

    def conveyor_belt_distance(self, speed_mm_per_sec, distance_mm, direction=1, interface=0):
        if speed_mm_per_sec > 100:
            raise pydobot.dobot.DobotException("Speed must be <= 100 mm/s")

        MM_PER_REV = 34 * math.pi  # Seems to actually be closer to 36mm when measured but 34 works better
        STEP_ANGLE_DEG = 1.8
        STEPS_PER_REV = 360.0 / STEP_ANGLE_DEG * 10.0 * 16.0 / 2.0  # Spec sheet says that it can do 1.8deg increments, no idea what the 10 * 16 / 2 fudge factor is....
        distance_steps = distance_mm / MM_PER_REV * STEPS_PER_REV
        speed_steps_per_sec = speed_mm_per_sec / MM_PER_REV * STEPS_PER_REV * direction
        return self._extract_cmd_index(self._set_stepper_motor_distance(int(speed_steps_per_sec), int(distance_steps), interface))

rpeach-sag avatar Mar 06 '20 21:03 rpeach-sag

I'm testing one a time. Let's start with the conveyor belt. I'm using Thonny that runs Python 3.7.3

BasicConveyorTest.py ` from serial.tools import list_ports

from pydobot import Dobot

port = list_ports.comports()[0].device device = Dobot(port=port, verbose=True)

device.conveyor_belt_distance(0.5, 100, 1, 0)

device.close() `

Shell showing: Traceback (most recent call last): File "/home/pi/Desktop/basicdobot.py", line 8, in device.conveyor_belt_distance(0.5, 100, 1, 0) File "/usr/local/lib/python3.7/dist-packages/pydobot/dobot.py", line 374, in conveyor_belt_distance self._set_stepper_motor_distance(motor_speed, distance, interface) File "/usr/local/lib/python3.7/dist-packages/pydobot/dobot.py", line 391, in _set_stepper_motor_distance msg.params.extend(bytearray(struct.pack('i', speed))) struct.error: required argument is not an integer

SForney54 avatar Mar 11 '20 21:03 SForney54

Just create a new file in your project called dobot_extensions.py with the following in it:

import pydobot
import math

class Dobot(pydobot.Dobot):
    def conveyor_belt_distance(self, speed_mm_per_sec, distance_mm, direction=1, interface=0):
        if speed_mm_per_sec > 100:
            raise pydobot.dobot.DobotException("Speed must be <= 100 mm/s")

        MM_PER_REV = 34 * math.pi  # Seems to actually be closer to 36mm when measured but 34 works better
        STEP_ANGLE_DEG = 1.8
        STEPS_PER_REV = 360.0 / STEP_ANGLE_DEG * 10.0 * 16.0 / 2.0  # Spec sheet says that it can do 1.8deg increments, no idea what the 10 * 16 / 2 fudge factor is....
        distance_steps = distance_mm / MM_PER_REV * STEPS_PER_REV
        speed_steps_per_sec = speed_mm_per_sec / MM_PER_REV * STEPS_PER_REV * direction
        return self._extract_cmd_index(self._set_stepper_motor_distance(int(speed_steps_per_sec), int(distance_steps), interface))

Then use it:

from serial.tools import list_ports

from dobot_extensions import Dobot

port = list_ports.comports()[0].device
device = Dobot(port=port, verbose=True)

device.conveyor_belt_distance(50, 100, 1, 0)

device.close()

rpeach-sag avatar Mar 12 '20 17:03 rpeach-sag

Conveyor belt. It worked as you suggested me to create a new extensions file and followed your example code.

Color sensor: I attempted to copy of your code for color sensor in the dobot.py. And I configured the port to GP5 where I plugged the color sensor.

colortest.py

from serial.tools import list_ports

from pydobot import Dobot

port = list_ports.comports()[0].device
device = Dobot(port=port, verbose=True)

(r, g, b) = device.get_color()
print(f'r:{r} g:{g} b:{b}') 

device.close()

Shell Showing:

pydobot: /dev/ttyUSB0 open
pydobot: >> AA AA:2:240:1::15
Lenght 2
b'\xf0\x01\x0f'
MessageID: 240
pydobot: << aa:aa:02:f0:01:0f
pydobot: >> AA AA:2:245:1::10
Lenght 2
b'\xf5\x01\n'
MessageID: 245
pydobot: << aa:aa:02:f5:01:0a
pydobot: >> AA AA:34:80:3:00 00 48 43 00 00 48 43 00 00 48 43 00 00 48 43 00 00 48 43 00 00 48 43 00 00 48 43 00 00 48 43:85
Lenght 10
b'P\x03V\x00\x00\x00\x00\x00\x00\x00W'
MessageID: 80
pydobot: << aa:aa:0a:50:03:56:00:00:00:00:00:00:00:57
pydobot: >> AA AA:18:81:3:00 00 48 43 00 00 48 43 00 00 48 43 00 00 48 43:128
Lenght 10
b'Q\x03W\x00\x00\x00\x00\x00\x00\x00U'
MessageID: 81
pydobot: << aa:aa:0a:51:03:57:00:00:00:00:00:00:00:55
pydobot: >> AA AA:10:82:3:00 00 20 41 00 00 48 43:191
Lenght 10
b'R\x03X\x00\x00\x00\x00\x00\x00\x00S'
MessageID: 82
pydobot: << aa:aa:0a:52:03:58:00:00:00:00:00:00:00:53
pydobot: >> AA AA:10:83:3:00 00 C8 42 00 00 C8 42:150
Lenght 10
b'S\x03Y\x00\x00\x00\x00\x00\x00\x00Q'
MessageID: 83
pydobot: << aa:aa:0a:53:03:59:00:00:00:00:00:00:00:51
pydobot: >> AA AA:2:10:0::246
Lenght 34
b'\n\x00\x8c\xf4AC\x00\x00\x00\x00\xc0.\x0fC\x00\x00\x00\x00\x00\x00\x00\x00`\xc8\xa9\xc0\x9e\xacZ\xc0\x00\x00\x00\x00\xbd'
MessageID: 10
pydobot: << aa:aa:22:0a:00:8c:f4:41:43:00:00:00:00:c0:2e:0f:43:00:00:00:00:00:00:00:00:60:c8:a9:c0:9e:ac:5a:c0:00:00:00:00:bd
pydobot: x:194.0 y:0.0 z:143.2 r:0.0 j1:0.0 j2:-5.3 j3:-3.4 j4:0.0
pydobot: >> AA AA:3:137:0:03:116
Lenght 5
b'\x89\x00\x00\x00\x00w'
MessageID: 137
pydobot: << aa:aa:05:89:00:00:00:00:77
r:False g:False b:False
pydobot: /dev/ttyUSB0 closed

Your thoughts? I must be writing something mistake in the code...

SForney54 avatar Mar 12 '20 20:03 SForney54

Couple of issues... I think they're issues with the firmware.

  • Try using GP2 - it seems to be the most reliable for the color sensor
  • GP5 doesn't seem to like switching the light source on and off...
  • Check which version of the color sensor you have - I have version2
  • If i run the code multiple times it occasionally seems to crash the robot and it stops responding... and i have to reset it (using the reset button). It only seems to happen between runs (never during a run), I think this might be a problem with the device.close() call but i'm not sure...
  • The color sensor is not great - It can't detect a yellow block (it can only tell you if it's red, green, or blue)
import pydobot
import math
import struct

from pydobot.message import Message

PORT_GP1 = 0x00
PORT_GP2 = 0x01
PORT_GP4 = 0x02
PORT_GP5 = 0x03

class Dobot(pydobot.Dobot):
    def conveyor_belt_distance(self, speed_mm_per_sec, distance_mm, direction=1, interface=0):
        if speed_mm_per_sec > 100:
            raise pydobot.dobot.DobotException("Speed must be <= 100 mm/s")

        MM_PER_REV = 34 * math.pi  # Seems to actually be closer to 36mm when measured but 34 works better
        STEP_ANGLE_DEG = 1.8
        STEPS_PER_REV = 360.0 / STEP_ANGLE_DEG * 10.0 * 16.0 / 2.0  # Spec sheet says that it can do 1.8deg increments, no idea what the 10 * 16 / 2 fudge factor is....
        distance_steps = distance_mm / MM_PER_REV * STEPS_PER_REV
        speed_steps_per_sec = speed_mm_per_sec / MM_PER_REV * STEPS_PER_REV * direction
        return self._extract_cmd_index(self._set_stepper_motor_distance(int(speed_steps_per_sec), int(distance_steps), interface))

    def set_color(self, enable=True, port=PORT_GP2, version=0x1):
        msg = Message()
        msg.id = 137
        msg.ctrl = 0x03
        msg.params = bytearray([])
        msg.params.extend(bytearray([int(enable)]))
        msg.params.extend(bytearray([port]))
        msg.params.extend(bytearray([version]))  # Version1=0, Version2=1
        return self._extract_cmd_index(self._send_command(msg))

    def get_color(self, port=PORT_GP2, version=0x1):
        msg = Message()
        msg.id = 137
        msg.ctrl = 0x00
        msg.params = bytearray([])
        msg.params.extend(bytearray([port]))
        msg.params.extend(bytearray([0x01]))
        msg.params.extend(bytearray([version]))  # Version1=0, Version2=1
        response = self._send_command(msg)
        print(response)
        r = struct.unpack_from('?', response.params, 0)[0]
        g = struct.unpack_from('?', response.params, 1)[0]
        b = struct.unpack_from('?', response.params, 2)[0]
        return [r, g, b]

Then use the code as follows:

from time import sleep

from serial.tools import list_ports

import dobot_extensions
from dobot_extensions import Dobot

port = list_ports.comports()[0].device

device = Dobot(port=port, verbose=True)
device.wait_for_cmd(device.set_color())
sleep(0.1) # Give the light a chance to illuminate properly
for i in range(10):
    (r, g, b) = device.get_color()
    print(f'r:{r} g:{g} b:{b}')
    sleep(1)
device.wait_for_cmd(device.set_color(enable=False))
device.close()

rpeach-sag avatar Mar 13 '20 10:03 rpeach-sag

Hi, I'm developing assembly lines with different dobots but I can't get the rail linear to work

carminelau avatar Mar 11 '22 07:03 carminelau

Color sensor:

    def set_color(self, enable=True, port=PORT_GP2):
        msg = Message()
        msg.id = 137
        msg.ctrl = 0x03
        msg.params = bytearray([])
        msg.params.extend(bytearray([int(enable)]))
        msg.params.extend(bytearray([port]))
        return self._extract_cmd_index(self._send_command(msg))

    def get_color(self, port=PORT_GP2):
        msg = Message()
        msg.id = 137
        msg.ctrl = 0x00
        msg.params = bytearray([])
        msg.params.extend(bytearray([port]))
        response = self._send_command(msg)
        r = struct.unpack_from('?', response.params, 0)[0]
        g = struct.unpack_from('?', response.params, 1)[0]
        b = struct.unpack_from('?', response.params, 2)[0]
        return [r, g, b]

what happen if use msg.id = 135

if you look at the dobot documentation 135 its the ID of steppers

Sant16 avatar Apr 12 '24 00:04 Sant16

Just create a new file in your project called dobot_extensions.py with the following in it:

import pydobot
import math

class Dobot(pydobot.Dobot):
    def conveyor_belt_distance(self, speed_mm_per_sec, distance_mm, direction=1, interface=0):
        if speed_mm_per_sec > 100:
            raise pydobot.dobot.DobotException("Speed must be <= 100 mm/s")

        MM_PER_REV = 34 * math.pi  # Seems to actually be closer to 36mm when measured but 34 works better
        STEP_ANGLE_DEG = 1.8
        STEPS_PER_REV = 360.0 / STEP_ANGLE_DEG * 10.0 * 16.0 / 2.0  # Spec sheet says that it can do 1.8deg increments, no idea what the 10 * 16 / 2 fudge factor is....
        distance_steps = distance_mm / MM_PER_REV * STEPS_PER_REV
        speed_steps_per_sec = speed_mm_per_sec / MM_PER_REV * STEPS_PER_REV * direction
        return self._extract_cmd_index(self._set_stepper_motor_distance(int(speed_steps_per_sec), int(distance_steps), interface))

Then use it:

from serial.tools import list_ports

from dobot_extensions import Dobot

port = list_ports.comports()[0].device
device = Dobot(port=port, verbose=True)

device.conveyor_belt_distance(50, 100, 1, 0)

device.close()

What have I not installed when I get this error:

Traceback (most recent call last): File "c:\Data\Programming\Dobot\PyDobot_conveyor_test01.py", line 9, in device.conveyor_belt_distance(50, 100, 1, 0) File "c:\Data\Programming\Dobot\dobot_extensions.py", line 22, in conveyor_belt_distance return self._extract_cmd_index(self._set_stepper_motor_distance(int(speed_steps_per_sec), int(distance_steps), interface)) ^^^^^^^^^^^^^^^^^^^^^^^ AttributeError: 'Dobot' object has no attribute '_extract_cmd_index'

Obviously pydobot is installed and working, but I'd like to use the conveyor belt as well. I don't care about the color sensor that much as it recognizes only 3 colors, not even the 4 color cubes that came with the belt...

baljo avatar May 10 '24 17:05 baljo

@baljo The comment you quote is from 2020 and the pydobot codebase looked different back then compared to now. I once found the commit where _extract_cmd_index was removed or renamed, but I can't remember on top of my head.

I am trying to do the same as you (and fixing a few issues with the library) but I have very little time for this at the moment. I have a student looking at the convoy belt with the newest version of the library.

jonascj avatar May 14 '24 06:05 jonascj

@baljo The comment you quote is from 2020 and the pydobot codebase looked different back then compared to now. I once found the commit where _extract_cmd_index was removed or renamed, but I can't remember on top of my head.

I am trying to do the same as you (and fixing a few issues with the library) but I have very little time for this at the moment. I have a student looking at the convoy belt with the newest version of the library.

@jonascj Ok, then I understand. I actually found another repo pydobot2 which is an oldish fork. I was positively surprised that the conveyor belt works with this, I have though not checked anything else. Anyhow, if you or your student progress with the newest library version, then I'd appreciate if you update e.g. this issue to notify us others about it. I'm also a teacher and using the robots for education.

baljo avatar May 14 '24 18:05 baljo

@baljo Great find, I'll have my student have a look at that fork :-P

There is actually quite a few forks with improvements that could be incorporated into this library.

jonascj avatar May 14 '24 20:05 jonascj