ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | Q&A
Ask Your Question

Generating an ikfast solution for 4 DOF arm

asked 2017-06-15 06:31:13 -0500

Bas gravatar image

updated 2017-06-15 06:32:40 -0500


I'm trying to make a 4DOF ikfast plugin. ROS version: Kinetic Ubuntu: Xenial

I'm following these instructions:

the first problem I run into is that I can't install the openrave package

sudo apt update
Ign:3 xenial InRelease                                                                  
Err:4 xenial Release                                                                    
  404  Not Found

and of course:

parallels@ubuntu:~/matilda-ikfast$ sudo apt install openrave0.8-dp-ikfast
[sudo] password for parallels: 
Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package openrave0.8-dp-ikfast
E: Couldn't find any package by glob 'openrave0.8-dp-ikfast'
E: Couldn't find any package by regex 'openrave0.8-dp-ikfast'

So I installed from source, following these instructions

With as result openrave 0.9 (the tags on de github account van 0.8.0 en 0.8.2 gave compilation errors.)

Then I succesfully made a collada file (openrave matilda.dae shows my robot)

parallels@ubuntu:~/matilda-ikfast$ matilda.dae --info links
name      index parents  
base      0              
base_link 1     base     
link_1    2     base_link
link_2    3     link_1   
link_3    4     link_2   
link_4    5     link_3   
tool0     6     link_4   
name      index parents

While I try to make the cpp file I get a sympy matrices.matrices.ShapeError:

parallels@ubuntu:~/matilda-ikfast$ python ../openrave/python/ --robot=matilda.dae --iktype=translationyaxisangle4d --baselink=0 --eelink=6 --savefile=output_ikfast61.cpp
INFO: trying to guess variable from [j0]
INFO: have only one variable left j0 and most likely it is not in equations [-pz*sin(j1) + cos(j1)/20 + 11029*cos(j2)/20000, pz*cos(j1) + sin(j1)/20 + 11029*sin(j2)/20000 + 123/200, sin(j1)*sin(j2)*cos(j3) - sin(j1)*sin(j3)*cos(j2) + sin(j2)*sin(j3)*cos(j1) + cos(j1)*cos(j2)*cos(j3) - cos(r00), -pz**2 - 123*pz*cos(j1)/100 - 123*sin(j1)/2000 - 30651159/400000000, -pz*sin(j1)*sin(j2) - pz*cos(j1)*cos(j2) - sin(j1)*cos(j2)/20 + sin(j2)*cos(j1)/20 - 123*cos(j2)/200, -pz*sin(j1)*cos(j2) + pz*sin(j2)*cos(j1) + sin(j1)*sin(j2)/20 + 123*sin(j2)/200 + cos(j1)*cos(j2)/20 + 11029/20000]
INFO: depth=0, c=2, iter=0/1, adding newcases: set([Abs(px) + Abs(py)])
Traceback (most recent call last):
  File "../openrave/python/", line 9548, in <module>
    chaintree = solver.generateIkSolver(options.baselink,options.eelink,options.freeindices,solvefn=solvefn)
  File "../openrave/python/", line 2297, in generateIkSolver
    chaintree.leftmultiply(Tleft=self.multiplyMatrix(LinksLeft), Tleftinv=self.multiplyMatrix(LinksLeftInv[::-1]))
  File "../openrave/python/", line 1122, in leftmultiply
    self.Pfk = Tleft[0:2,0:2]*self.Pfk+Tleft[0:2,3]
  File "/home/parallels/.local/lib/python2.7/site-packages/sympy/matrices/", line 404, in __mul__
    return matrix_multiply(self,a)
  File "/home/parallels/.local/lib/python2.7/site-packages/sympy/matrices/", line 2458, in matrix_multiply
    raise ShapeError()

Any ... (more)

edit retag flag offensive close merge delete


After Hydro, I've never bothered installing OpenRAVE - using binaries or from sources. I've always just used docker/personalrobotics/ros-openrave.

gvdhoorn gravatar image gvdhoorn  ( 2017-06-16 04:11:00 -0500 )edit

Also: see #q196753 for a question about 5dofs, but the same approach should work for 4dofs. I'm not sure that will solve / work around the issue that you are seeing, but it's worth a try.

Finally: probably not something you want to hear, but unfortunately we're only users of OpenRAVE/IKFast just as you. If something is really broken / not working as it should, rdiankov/openrave/issues would be the place to report it.

gvdhoorn gravatar image gvdhoorn  ( 2017-06-16 04:12:39 -0500 )edit

I've tried the linked docker image, where I get other kinds of errors (matrices size mismatch etc, but not the error above). I followed your links re. 5DOF's too. This looks like it's going to be a non-trivial exercise with limited chance of success...

Bas gravatar image Bas  ( 2017-07-05 04:12:25 -0500 )edit

...Going to look into manually coding the IK. Thanks for the links and looking into my problem

Bas gravatar image Bas  ( 2017-07-05 04:12:53 -0500 )edit

This looks like it's going to be a non-trivial exercise [..]

It's actually about the same amount of work as the regular procedure to generate an IK plugin. The .dae you need to make anyway, and then only the small additional wrapper is needed. After that copy-paste the command line I already gave as an example in #q196753.

I'm probably a little biased, but it shouldn't be too much work actually.

gvdhoorn gravatar image gvdhoorn  ( 2017-07-05 07:55:52 -0500 )edit

Ok, i get held back by the links to the openrave mailing list and my experience with my non-standard kinematics. I'll try the wrapper approach.

Bas gravatar image Bas  ( 2017-07-05 08:34:28 -0500 )edit

Don't spend too much time on it: I can't guarantee that it'll actually work. I just wanted to clarify that it shouldn't be too different from the 'regular' approach wrt the amount of work.

gvdhoorn gravatar image gvdhoorn  ( 2017-07-05 14:31:30 -0500 )edit

I just spent some time on this, and after fiddling a little with the personalrobotics Docker image and writing a very minimal OpenRAVE wrapper xml file I got it to generate a translationyaxisangle4d cpp. I haven't tested it yet, will do that later today.

gvdhoorn gravatar image gvdhoorn  ( 2017-07-06 05:09:02 -0500 )edit

3 Answers

Sort by ยป oldest newest most voted

answered 2017-07-06 11:52:22 -0500

gvdhoorn gravatar image

updated 2017-07-09 16:01:16 -0500

This is what I did to get OpenRAVE to generate an IKFast plugin for your urdf.

I'll assume that you've already:

  • converted the top-level .xacro to a .urdf, and
  • have converted it to Collada (using rosrun collada_urdf urdf_to_collada ..)

I decided to use the personalrobotics/ros-openrave Docker image, as installing OpenRAVE from sources on recent Ubuntu / Debian versions is not trivial, and takes quite some time (as you probably discovered).

We need to tweak the image a bit though, so:

$ mkdir /tmp/prro_work && cd /tmp/prro_work
$ cat << EOF > Dockerfile
FROM personalrobotics/ros-openrave
RUN apt-get update || true && apt-get install -y --no-install-recommends build-essential python-pip liblapack-dev && apt-get clean && rm -rf /var/lib/apt/lists/*
RUN pip install sympy==0.7.1

# Replace `$DOCKER_IMAGE` with some descriptive name here
$ docker build -t $DOCKER_IMAGE .

This makes pip install an older version of sympy in /usr/local, which is then used by OpenRAVE instead of the sympy that is installed by apt. The IKFast generator is very specific about the version of sympy and this version seems to work - in any case it works with your .dae.

Now wait for Docker to build the new image.

Then we need a small wrapper 'robot' for OpenRAVE:

  <Manipulator name="NAME_OF_THE_ROBOT_IN_URDF">

save this as wrapper.xml (you can obviously change the name if you want). OpenRAVE supports relative filenames for the file attribute of the robot element in our wrapper.xml, so it's easiest if you place wrapper.xml in the same directory that contains the .dae of your robot model.

And make sure to update base_link and tool0 to whatever you want as your base and effector links (these elements correspond to the --baselink and --eelink arguments that you pass to normally, but by name, not an index). In almost all cases these should correspond to whatever you have modelled as those links in your urdf.

Now generate the plugin:

$ cd /to/wherever/you/have/your/dae/and/your/wrapper
$ mkdir output

# the first volume here is the 'work dir', ie: where we have stored the wrapper and
# the Collada file.
# the second volume is where OpenRAVE stores the generated `.cpp`.
# there is no 'output file' argument to ` --database inversekinematics ..`,
# so this will have to do.
# make sure to replace $DOCKER_IMAGE with whatever you used earlier
$ docker run -it --rm -v `pwd`:/ikfast -v `pwd`/output:/root/.openrave $DOCKER_IMAGE --database inversekinematics --robot=/ikfast/wrapper.xml --iktype=translationyaxisangle4d --iktests=1000

Because we installed build-essential inside the image, we can ask OpenRAVE to run some IK tests for us. OpenRAVE will automatically compile the plugin after it has generated it and run the tests. Pay attention to the final output. On my machine it is something like:

openravepy.databases.inversekinematics: testik, success rate: 1.000000, wrong solutions: 0.000000, no solutions: 0.000000, missing solution: 0.036000

If everything went well, you should now have a ikfast71.TranslationYAxisAngle4D.0_1_2_3 ... (more)

edit flag offensive delete link more


Note that I didn't bother with uid and gid with Docker, so the generated files will be owned by root.

gvdhoorn gravatar image gvdhoorn  ( 2017-07-06 11:54:32 -0500 )edit

Note also that depending on your urdf it may be necessary to add a direction child tag to the Manipulator tag in the wrapper xml. Refer to Defining Manipulators in the OpenRAVE docs for more info.

gvdhoorn gravatar image gvdhoorn  ( 2017-07-06 11:59:14 -0500 )edit

This same procedure should work for other robots as well, just make sure to select a proper iktype for those models (instead of translationyaxisangle4d).

gvdhoorn gravatar image gvdhoorn  ( 2017-07-06 12:09:04 -0500 )edit

Thanks @gvdhoorn This generates the files as you described, and indeed I experienced installing openrave as non-trivial. I will continue with the correct tutorial. Thanks for all your patience! Next time we meet I'll buy you a nice cold beverage and a big Burger!

Bas gravatar image Bas  ( 2017-07-06 13:39:48 -0500 )edit

I don't think it's changed too much, but the most recent version of the tutorial can be found here.

gvdhoorn gravatar image gvdhoorn  ( 2017-07-06 14:22:07 -0500 )edit

To add to this - in case you don't go with the Docker image, make sure you don't have mpmath installed.

hamzamerzic gravatar image hamzamerzic  ( 2017-12-07 06:42:01 -0500 )edit

Complementing gvdhoorn's answer, I've posted an exmaple xml file here:

yijiangh gravatar image yijiangh  ( 2018-03-17 20:19:56 -0500 )edit

I have created a tool for online generation of ikfast solvers - meaning no need to do any manual setting up. You can find the tool here:

hamzamerzic gravatar image hamzamerzic  ( 2018-03-17 20:33:34 -0500 )edit

answered 2020-11-19 16:27:06 -0500

lukicdarkoo gravatar image

updated 2022-09-23 09:43:02 -0500

We developed a Docker image that is slightly simpler to use (than OpenRave's one) and it also generates a Python library:

To generate *.cpp files a single command is enough:

docker run -v [folder_with_robot.urdf]:/output cyberbotics/pyikfast [base_link] [effector]

The command above will also generate a Python library, so you can install it as:

pip3 install [folder_with_robot.urdf]
edit flag offensive delete link more

answered 2018-07-30 10:03:16 -0500

mgangl gravatar image

Hello Ros community. Warning! Be careful with the link posted by hamzamerzic. I generated the ikfast code for an ur-10 using the posted link. It took about 6 hours. The next day I saw in the network history, an upload of about 300 GB! I am not sure, if the posted webpage is trustworthy. Maybe there was just any loop running in the background. @hamzamerzic: can you explain yourself that traffic? Setup: Oracle VM VirtualBox, Ubuntu 16.04.4 LTS

edit flag offensive delete link more


Hi, that is quite surprising. There definitely is a loop running in the background which ensures that the console output is printed (what you see during generation of ikfast). The way it currently works is it prints out the full output every few seconds, which might pile up. I will look into this.

hamzamerzic gravatar image hamzamerzic  ( 2018-07-30 12:15:56 -0500 )edit

After another test today, i can confirm the observation. The traffic is increasing over time! Further Information: I had run the code generation two times (in 2 tabs) at the same time (for two different setups).

mgangl gravatar image mgangl  ( 2018-07-31 04:25:30 -0500 )edit

Thanks for checking this @mgangl I've only used this for jobs lasting up to half an hour or so, and there the files were of reasonable size, so I haven't noticed this earlier.I will try to find a better way of passing the log without requiring the user to "download" the full file every time.

hamzamerzic gravatar image hamzamerzic  ( 2018-07-31 05:29:23 -0500 )edit

Just an update on this. As mentioned earlier, the reason for the high bandwidth is that I am writing the full length build output periodically. The period has been increased from 0.5 to 5 seconds, until I find a better solution.

hamzamerzic gravatar image hamzamerzic  ( 2018-09-09 18:25:45 -0500 )edit

Does your online solution work for 4 DOF arm? If yes, what kinematic solver could you recommend?

Wintermute gravatar image Wintermute  ( 2018-09-19 06:51:36 -0500 )edit

I've never tried it on 4 DOF problems, I've only used 6 and 7 DOF solvers. As far as I know, ikfast does not work on underactuated problems - you have more info here. Otherwise look into numerical ik solvers.

hamzamerzic gravatar image hamzamerzic  ( 2018-09-19 16:34:45 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools



Asked: 2017-06-15 06:31:13 -0500

Seen: 3,167 times

Last updated: Sep 23 '22