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

A wild PoppyErgoJr has appeared!

It is still work in progress, but we already have a working prototype of this new Poppy Creature. It is based on the really low-cost dynamixel XL-320 motors. Those motors are now supported in pypot since version 2.2!

Thanks to @jgrizou, all the 3d printed parts were done using OpenSCAD and can thus be easily modified, hacked, tuned!

The hardware and software are already available on the github repository. It still needs some work but we are really excited to see what people will be able to do with this new creature. Or even better what kind of new creature they can imagine with this low-cost solution!

Oh and btw it can jump pretty well ^^
The code to make your own PoppyErgoJr jump is available as a notebook here.

https://vine.co/v/OxlTF6inWpV

13 Likes

This is pretty cool, good job guys :smile:
What do you mean by ā€œlow-costā€? It would look good on my new desk ā€¦

About 20ā‚¬ per motor.

[TEASING MODE ON]
Experiments with Explauto are on their way @Clementā€¦


[TEASING MODE OFF]

6 Likes

Flowers rule :smile:

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: (ģ£¼)ė”œė³“ķ‹°ģ¦ˆ

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