Closed ntjess closed 4 years ago
Hi @ntjess, for your particular case the best is not to use YAML templates but create instances directly. Unfortunately, the DynamixelBus cannot be initiated now without a robot reference - it's something I've already raise as an issue #61 .
Once this is solved you should be able to do something like this:
from roboglia.dynamixel import DynamixelBus
dyn = DynamixelBus(baudrate=1000000, protocol=2.0, port='/dev/ttyUSB0')
dyn.open()
# example of reading present position
device_id = 1 # or whatever the ID of your servo is
address = 132 # present position
position = dyn.packet_handler.read4ByteTxRx(dyn.port_handler, device_id, address)
print(position)
# example of writing goal position
address = 116 # goal position
value = 2048
dyn.packet_handler.write4ByteTxRx(dyn.port_handler, device_id, address, value)
Even better, to take advantage of the device classes you might also do this:
from roboglia.dynamixel import DynamixelBus, DynamixelDevice
dyn = DynamixelBus(baudrate=1000000, protocol=2.0, port='/dev/ttyUSB0')
# there is no device XM540 yet, but this is just an example:
servo = DynamixelDevice(bus=dyn, dev_id=1, model='XM540')
dyn.open()
# now the `servo` should have all the registers defined by the model so you can do something like:
# will print the current position in range 0-4095
print(servo.present_position.value)
# if there are clone registers defined you could have:
print(servo.present_position_deg.value)
# and you can also set the values:
servo.goal_position.value = 1024
# or with clones set the value in degrees:
servo.goal_position_deg.value = 45
Fantastic, this is what I was looking for. I didn't see the code for dynamic instantiation listed in the documentation. I am only able to go into lab once a week at the moment, but I will definitely try this out next Monday. If I can manage to get it working, I would be happy to expand the documentation for non-complex use-cases -- is that something you're interested in, or is the readthedocs
material designed to be YAML/high-level only?
I've posted a couple of PRs to the master and made some updates to the documentation. It should be possible to do the things listed above (or the ones indicated in the quick_start).
Take your time with using the framework and feel free to send any PRs to the code or documentation if you please.
I will be more than happy to merge them.
Thanks.
Sorry - forgot to mention that you will need to install from the GitHub repo and not from PyPi as is not yet deployed there:
git clone https://github.com/sonelu/roboglia.git
cd roboglia
pip install .
Just a note -- pip install
does not work for me. It is because after installing roboglia, the line
import yaml
turns into
from . import yaml
And since yaml.py
shadows the yaml
package, python cannot find safe_load
:
Traceback (most recent call last):
File "C:\Users\user\Miniconda3\envs\env\lib\site-packages\roboglia\utils\yaml.py", line 19, in load_yaml_with_include
main_dict = yaml.safe_load(f)
AttributeError: module 'roboglia.utils.yaml' has no attribute 'safe_load'
Sorry, my bad, I've fixed it now and should work.
You'll need to refresh:
git pull origin master
Let me know how it goes.
Thanks for your help, it worked! For future users looking at this issue, make sure to include the line
servo.torque_enable.value = True
Otherwise the arm will not move.
I found this library when looking for up-to-date dynamixel libs on pypi. It totally blows the competition out of the water in terms of capabilities! The only problem is there's almost too much information to easily get started.
If I just wanted to send a "move up -> move down" command to my dynamixel XM540 servo, what's a simple method of accomplishing this? I see that YAML files already exist here which have the same control table config (like MX28v2), so what other information would be required for a MWE?
Again, great work!
EDIT: The Quick Start guide is comprehensive and readable, but doesn't quite give me a sense of the minimal amount of required information. As a result, it's a little intimidating to morph the example code into my use case.