PDA

View Full Version : Kinematic simulator in python?



psyclops
04-29-2013, 01:01 PM
Hi folks! Does anyone know of a kinematics simulator package, preferably written in python? I have a new hexapod robot Grinder ( http://forums.trossenrobotics.com/robots.php?project_id=49#ad-image-0 ) that I am writing IK software for. I have the IK equations ready to go, but it would be so much faster and simpler to create a simulator for the robot in software so that I can write and test the IK framework without needing the actual robot...

I am currently using the lib_robotis.py libraries from hizook, but I am in the process of rolling the code into ROS. Servos are dynamixels, but I am hoping to write a completely standalone simulator.

Any ideas?

cheers,

nick.

jwatte
04-29-2013, 04:37 PM
A (long) while back, I used SWIG to generate bindings for the ODE physics simulation package.
The Python sites list a library called PyODE which I believe might still be maintained as a ready-made option.
Another high quality physics simulation library is Bullet; there seems to exist a pybullet open source library but it doesn't seem well maintained.

psyclops
04-29-2013, 07:52 PM
A (long) while back, I used SWIG to generate bindings for the ODE physics simulation package.
The Python sites list a library called PyODE which I believe might still be maintained as a ready-made option.
Another high quality physics simulation library is Bullet; there seems to exist a pybullet open source library but it doesn't seem well maintained.

Thanks for the tip, looks like I can do some interesting things with pyODE and visualPython. I had been looking at omd but it doesn't seem to have much support and the original site is gone... I'll install pyODE and visualPython and post my results...

cheers,

n.

psyclops
05-02-2013, 04:24 PM
I have had some success with the vpython approach. So far I have a basic linkage system built up, integrated with my IK code for generating the neccesary coordinates. I have to create a new frame for each linkage, then in each step move it to its new position and set the axis to its new orientation. Not pretty (codewise) but it works. I have attached two files if you want to try it. You can get vpython at http://www.vpython.org/

grinder_simulator_01.py - Z/Y linkage mechanism
grinder_simulator_02.py - X/Z/Y mechanism with Z/Y mechanism rotating around X axis. Tricky... still working on it.
4663

Xevel
05-02-2013, 04:43 PM
I have written a simulator for Xachi a while back, from scratch, using VPython for the visualization.
You might be able to either reuse some parts of it, or maybe just get some ideas, since it's not made to be generic/reusable... I wrote it quite quickly and it developed organically :/

http://xevel.fr/other/Xachikoma_20130422.zip
(http://xevel.fr/other/Xachikoma_20130422.zip)
There are 3 folders:
* Simu: contains all the simulator-related files. Most of them are not
The simulator itself is ran with Simu/xachikoma_simu.py.
Open it in VIDLE then run it with F5. There might be some folders to add to the python path if the xachi package is not found.
A lot of stuff in this folder are stand alone little experiments, or visualization of what the robot sees (like the LDS, the CMUcam...) and is turned off by default.
ik_visu.py are the visualization classes, manipulator.py has some useful little things.

* xachi: contains all the code running in the robot. The IK code is in xachi/control/ik_nodes.py, with some more stuff in ik_helpers.py.

* xachiRemote: a C# app to remote control Xachi, based on ZMQ for communication, with ways to create various combination of keys and different modes of control - that's what makes xachi move smoothly right now :) But that's not the topic.

The idea is that I have a tree of IK nodes, each one knows how to solve its own IK, body being the root and each limb being one of its children. Solving the IK problem stores the mathematical state (angles in radians) in the IK node itself.
These values are either used to transform that into commands for the servo (on the robot) or for the visualization (simu).
I haven't written rotation manipulators but I could if needed.




Since then, I have just started (in the plane back from San Francisco actually!) new simu, just to have a look at some leg configurations and the associated control software for my next beast (for Mech Warfare!):
http://xevel.fr/other/new_quad.py
Download it and put it in the Simu folder of the previous archive, it uses some helper stuff that lies around - I think.

There is very little to it right now, but it might give you some ideas about how to make some simple stuff.
Currently, it only has a class that represents a servo and the kinematics link from it to the next actuator.

I'm sure there is a lot of obscure stuff around, feel free to ask, I might even be able to make a stripped down "educatioal" version (=easier for people to understand how it works so that they can benefit from reading the source code or even reuse parts of it) if there is some interest...



(http://xevel.fr/other/new_quad.py)

psyclops
05-02-2013, 06:06 PM
What version of vpython were you using? I am getting a variety of errors... likely because it's based on an old version.

Xevel
05-02-2013, 10:37 PM
I'm using Python 2.7 and the latest associated VPython version, 6.05. Are you using Python 3.x?
What errors do you get ?

psyclops
05-02-2013, 10:42 PM
OK I figured it out, made a couple of small changes to ik_visu.py and got it working. Nice simulator! I'm definitely stealing your control panel...


def __init__(self, body, frame_in):

self.body = body

self.body_frame = frame(frame = frame_in, pos = body.pos)

self.ring = ring(frame=self.body_frame, pos=(0,0,58.5), axis=(0,0,1), radius = 100, thickness=2, color = color.blue)

self.pyramid = pyramid(frame=self.body_frame, pos=(100,0,58.5), size=(10,17,5), color=color.red )

psyclops
05-03-2013, 09:16 PM
Success! I realized I could massively simplify the simulator by a) reducing all linkages to cylinders and b) only using frames for each leg, and c) simply moving the cylinder linkage ends to the x,y coords generated by my IK equations. I rewrote the code in about an hour and now have a full robot simulator that I can throw foot x,y,z coords at and it will show me visually what the robot is doing. Awesome.

See python code at url below. I have a simple demo going with all six legs swinging back and forth and up and down. Now I need to integrate it into my robot code...

http://www.gotrobots.com/grinder/simulator/grinder_simulator.py

(http://www.gotrobots.com/grinder/simulator/grinder_simulator.py)

Xevel
05-04-2013, 05:06 AM
Looks very cool :)
The equations are, like you showed me, much faster when developed and written with only trigonometry instead or vectors/matrices, but I still find them a little harder to read ;)
I might take that into account for my next project where performance will be an important factor ^^

Can't wait to see what gait you will make with that tool !

psyclops
05-06-2013, 08:47 PM
Yes, the trig seems very fast. I had to add a whole extra IK routine in to back-calculate the foot position from the wheel-on-ground position for skating, so I can ensure that the wheel is always touching the ground whatever angle the leg is at (since the leg angle affects the vertical distance between foot and wheel). I was going to roll the resultant IK into a separate routine for skating, but it's fast enough that I can run the back-calculate and then run the full IK for the foot (which contains some redundant calcs) without any apparent slow down...

I updated the code at http://www.gotrobots.com/grinder/simulator/grinder_simulator.py with the latest code showing wheel-contact IK working in a skating algorithm...

TXBDan
05-08-2013, 12:36 PM
This is cool, i got your project up and running yesterday. I've never used Python before so i'm trying to wrap my head around it, but i'd like to build a simple 3DOF hex model that everyone can use. I'll post it up if/when i get there.

Great tool!

psyclops
05-15-2013, 10:00 AM
This is cool, i got your project up and running yesterday. I've never used Python before so i'm trying to wrap my head around it, but i'd like to build a simple 3DOF hex model that everyone can use. I'll post it up if/when i get there.

Great tool!

Great, can't wait to see it... The technique is actually pretty straightforward and extensible. The idea is that you build all linkages initially along a line, naming each end. Each leg is placed within a frame. Then you calculate the x,y coords of each point and move the end points to these coords. As a final step each leg frame is rotated by the leg angle.

This works great for my linkage assembly; for a more general motor chain assembly each motor will need to be in its own frame but frames can be nested to achieve the desired results.

TXBDan
05-15-2013, 10:17 AM
I got it almost done, but got distracted when my hex kit arrived!

I wanted to be able to test my IK code so my method is pretty convoluted. I'm basically running the leg IK function and then running that servo angle output into a FK function so that i can get the X,Y,Z coords for all of the joints. Then i use those XYZs to update the link cyclinder and sphere positions. It mostly works but my leg frames are messed up and there's a bug in my IK or FK somewhere.

I'm really annoyed by the vpython default XYZ orientation. It's screwing up everything i have in my head. Is there a way to redefine the default orientation behavior?

I'll try to fix it, but for now i'm pretty obsessed with my hex kit

Xevel
05-15-2013, 01:30 PM
I'm really annoyed by the vpython default XYZ orientation. It's screwing up everything i have in my head. Is there a way to redefine the default orientation behavior?

You can try setting a different value of scene.up:

scene.up=(0,0,1)
It might be enough, it might not be... I had a hard time adjusting to the way VPython orients stuff too. This made it better for me.

And BTW you can use this to show the orientation of stuff (I have one in the main scene, then another one in each frame to have a better understanding of what's happening).



class vect_base:
def __init__(self, pos=(0,0,0), size=10, number='', parent_frame=None):
if parent_frame == None:
self.coord = frame()
else:
self.coord = frame(frame=parent_frame)
coordinate_pos = vector(pos)
ref_x = arrow(frame=self.coord, pos = coordinate_pos, axis=(size,0,0), shaftwidth=3, color=color.red)
label(frame=self.coord, pos = coordinate_pos+(size*0.8,0,0), text='x'+str(number), box=false, opacity=0.1, height=size)
ref_y = arrow(frame=self.coord, pos = coordinate_pos, axis=(0,size,0), shaftwidth=3, color=color.green)
label(frame=self.coord, pos = coordinate_pos+(0,size*0.8,0), text='y'+str(number), box=false, opacity=0.1, height=size)
ref_z = arrow(frame=self.coord, pos = coordinate_pos, axis=(0,0,size), shaftwidth=3, color=color.blue)
label(frame=self.coord, pos = coordinate_pos+(0,0,size*0.8), text='z'+str(number), box=false, opacity=0.1, height=size)

TXBDan
05-16-2013, 09:14 AM
Thanks, that is very helpful.