Birth of Poppy Ergo Jr and support for low-cost XL-320 motors

Hi, the aim is that the xl-320 arm learns by itself how to move ? If you achieve to follow a direction with this kind of dynamics, it’s cool !

Hi Pierre
Have you un exported STL files, i don’t found it in repository ?

Here:

Ok super ! …thanks

Hi
What type of power supplie do you use ?

XL320 specifications: http://support.robotis.com/en/product/dynamixel/xl-series/xl-320.htm

Voltage: 6 ~ 8.4V (Recommended Voltage 7.4V)

Amperage: depends on the number of motors and their use, we recommend a power supply handling at least 2A, see below:

Just to be sure I’ll plug correctly the xl-320
1 : GND
2 : VCC+
3 : DATA

Someone could confirm ?


Cable for USB2

cable for xl-320

Yes, thats it!
I build a small adaptation circuit :

Problem to find the motors :

c:>herborist

nothing hapened (no error message)?

Try to acces the motors. It works with one motor. But with two, I raise an error with dxl_io.scan()

Error message more readable here


DxlCommunicationError Traceback (most recent call last)
in ()
----> 1 print(dxl_io.scan())

c:\python27\lib\site-packages\pypot-2.7.1-py2.7.egg\pypot\dynamixel\io\abstract_io.pyc in scan(self, ids)
219 def scan(self, ids=xrange(254)):
220 “”" Pings all ids within the specified list, by default it finds all the motors connected to the bus. “”"
–> 221 return [id for id in ids if self.ping(id)]
222
223 # MARK: - Specific Getter / Setter

c:\python27\lib\site-packages\pypot-2.7.1-py2.7.egg\pypot\dynamixel\io\abstract_io.pyc in ping(self, id)
212
213 try:
–> 214 self._send_packet(pp, error_handler=None)
215 return True
216 except DxlTimeoutError:

c:\python27\lib\site-packages\pypot-2.7.1-py2.7.egg\pypot\dynamixel\io\abstract_io.pyc in _send_packet(self, instruction_packet, wait_for_status_packet, error_handler, _force_lock)
522
523 if not error_handler:
–> 524 return self.__real_send(instruction_packet, wait_for_status_packet, _force_lock)
525
526 try:

c:\python27\lib\site-packages\pypot-2.7.1-py2.7.egg\pypot\dynamixel\io\abstract_io.pyc in __real_send(self, instruction_packet, wait_for_status_packet, _force_lock)
490 return
491
–> 492 status_packet = self.__real_read(instruction_packet, _force_lock=True)
493
494 logger.debug(‘Receiving %s’, status_packet,

c:\python27\lib\site-packages\pypot-2.7.1-py2.7.egg\pypot\dynamixel\io\abstract_io.pyc in __real_read(self, instruction_packet, _force_lock)
512 except ValueError:
513 msg = ‘could not parse received data {}’.format(bytearray(data))
–> 514 raise DxlCommunicationError(self, msg, instruction_packet)
515
516 return status_packet

DxlCommunicationError: could not parse received data ÿÿýaU^eÿ after sending DxlPingPacket(id=1)

From what the error shows I’m guessing you did not configure your motors so they all have the same id: 1. Thus when you plugged multiple motors on the same line collisions occurs (DxlCommunicationError).

Did I guess right?

Right :smile:
How should I configure my motors ?

Thanks to @Manon, you can do it using herborist: http://poppy-project.github.io/pypot/herborist.html

2 Likes

I have an unstable behavior with the mini4dof. It works for about 30 seconds and after, one led of the USB2Dynamixel switch off and the other slowly flashes and the motors don’t move anymore. It raise an error in pypot : http://nbviewer.ipython.org/github/jjehl/mini_dof/blob/master/4dof_mini.ipynb

No problem to control with low level IO.

Yeah I have the same issue as you do. I interpret this very odd “None Error” on the XL-320 as a current issue.

A very simple way to circumvent the problem is to change the way errors are handled in pypot. You can add the following lines to the BaseErrorHandler:

def handle_none_error(self, packet):
    pass

This should work but it’s not really fixing the problem. I’m stil investigating why those issues are raised. I let you know if I found anything. Otherwise I’ll just try/catch the error…

Hello,

Another strange things (maybe a relation ?) The goto method doesn’t reach the position. The time is respected but the goal position is clearly not reach.
The difference is important in dummy mode and huge in minjerk mode. For example, this small sequence :

poppy.m1.goto_position(40,2)
poppy.m2.goto_position(40,2)
poppy.m4.goto_position(90,2)
poppy.m3.goto_position(130,3,wait=True)
poppy.m1.goto_position(-40,2)
poppy.m2.goto_position(-40,2)
poppy.m4.goto_position(-90,2)
poppy.m3.goto_position(-130,3,wait=True)

Fot the motor 2, no problem :

Dummy

Minjerk

I guessed that with the wait argument the motor 3 (m3) should reach his position before to continue the running but in reality the wait=true act like a time.sleep=(3) and m3 never goes to 130 degrees. About 100 in dummy and less than 50 using minjerk.

Dummy

Minjerk

Is it a reproductible issue or a problem with my computer ?

EDIT 1 :
More info about my problem to control the motors : Pypot main update loop seems to run slowly than 50 Hz and this raise problem because the calculated time become different from the real time. I’ll need to investigated more.

Is there an URDF model for the mini_dof ?

Sorry @juju I still haven’t find time to check your problem in details.

Yet,

Yes! This a very important point! You can not force the run loop (or any other loops BTW) to really run at 50Hz except if you are running a real time OS.

Thus, if you want to do something time dependant, you should follow the examples we have used for the sinus primitive. The idea is not to suppose your update loop will be called every 20ms but to directly get the current time from the system. BTW, this is also the only way you will be able to have the same code running on the simulator (where times is not the same than in reality) and on the real robot:

pos = self._amp * numpy.sin(self._freq * 2.0 * numpy.pi * self.elapsed_time +  self._phase * numpy.pi / 180.0) + self._offset

Here self.elapsed_time will always get you the current time on your system (real or simulated). The precision of the time will depend on your system.

2 Likes

Changing the latency time make things better,

in :  %timeit dxl_io.get_present_position((1, 2, 3, 4))
out : 100 loops, best of 3: 6.91 ms per loop

but is only part of the problem.

I realise that changing the time for movement doesn’t change the goal_speed

poppy.m4.goto_position(130,1,wait=True)
poppy.m4.goto_position(0,1,wait=True)
poppy.m4.goal_speed

Out : 89.244

Faster :

poppy.m4.goto_position(130,0.5,wait=True)
poppy.m4.goto_position(0,0.5,wait=True)
poppy.m4.goal_speed

Out : 89.244

I have an electronic beginner question about the molex connector :
Here it is the schematic of the molex connector for dynamixel servo in circuitmaker :

Here it is the real connector : http://www.molex.com/pdm_docs/adobe3D/22-03-5035.pdf

How can I know where is the pin number 1 of the schematic on the real connector ?
I try to have a look on the datasheet http://www.molex.com/pdm_docs/sd/022035035_sd.pdf but found nothing about a numerotation of the pin ? Also try to find out something on circuitmaker with the link between real and schematic but didn’t success :sob:

you can find pin number and robotis pinout on the XL320 datasheet. This is not perfect but at the bottom you have a small pictures with pin number :

http://support.robotis.com/en/product/dynamixel/xl-320.htm

We have a really new board called pixl that should interest you :

http://workspace.circuitmaker.com/Projects/78A4FE38-92CD-4DAB-9B5A-15E9EAD0FAC1

Ok thanks for the pin number.

I had a look on the RPI pixl board and I wonder what is the purpose of this board ?