Rosanswers logo


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

I'm following these instructions: http://wiki.ros.org/Industrial/Tutorials/Create_a_Fast_IK_Solution

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

sudo apt update
Ign:3 http://ppa.launchpad.net/openrave/release/ubuntu xenial InRelease                                                                  
Err:4 http://ppa.launchpad.net/openrave/release/ubuntu 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 http://fsuarez6.github.io/blog/workstation-setup-xenial/

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$ openrave-robot.py 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/ikfast.py --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/ikfast.py", line 9548, in <module>
    chaintree = solver.generateIkSolver(options.baselink,options.eelink,options.freeindices,solvefn=solvefn)
  File "../openrave/python/ikfast.py", line 2297, in generateIkSolver
    chaintree.leftmultiply(Tleft=self.multiplyMatrix(LinksLeft), Tleftinv=self.multiplyMatrix(LinksLeftInv[::-1]))
  File "../openrave/python/ikfast.py", 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/matrices.py", line 404, in __mul__
    return matrix_multiply(self,a)
  File "/home/parallels/.local/lib/python2.7/site-packages/sympy/matrices/matrices.py", line 2458, in matrix_multiply
    raise ShapeError()

Any pointers on how to tackle this? Thanks,

Originally posted by Bas on ROS Answers with karma: 5 on 2017-06-15

Post score: 0

Original comments

Comment by gvdhoorn on 2017-06-16:
After Hydro, I've never bothered installing OpenRAVE - using binaries or from sources. I've always just used docker/personalrobotics/ros-openrave.

Comment by gvdhoorn on 2017-06-16:
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.

Comment by Bas on 2017-07-05:
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...

Comment by Bas on 2017-07-05:
...Going to look into manually coding the IK. Thanks for the links and looking into my problem

Comment by gvdhoorn on 2017-07-05:\

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.

Comment by Bas on 2017-07-05:
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.

Comment by gvdhoorn on 2017-07-05:
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.

Comment by gvdhoorn on 2017-07-06:
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.

Comment by gvdhoorn on 2017-07-06:
And a general comment: you linked to the "Create a kinematics solution using IK Fast" tutorial in your OP. You did notice that that tutorial has been deprecated, right? There is an admonition at the top of the page linking to the correct / updated version of the instructions.

Comment by Bas on 2017-07-06:
I must have missed the info that it's deprecated. Thanks for thinking along and helping out. I have recently fixed my macro file and added the collada file in this branch

Comment by Bas on 2017-07-06:
I'm hampered by some other work and I'm freeing up this evening to work on this. If you gain some insights I would be very interested.

Comment by gvdhoorn on 2017-07-06:
re: branch: I've just used master. But the process is relatively straightforward and repeatable, so you should be able to do it yourself as well with any urdf.


2 Answers 2


Rosanswers logo

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 ikfast.py 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 `openrave.py --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 openrave0.9.py --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.cpp and a ikfast.h in the output/ dir that we created earlier. You should be able to continue with the tutorial now and finish creating the MoveIt IKFast plugin.

Documentation I used for this is basically what I referenced in #q196753.

Originally posted by gvdhoorn with karma: 86574 on 2017-07-06

This answer was ACCEPTED on the original site

Post score: 6

Original comments

Comment by gvdhoorn on 2017-07-06:
Note that I didn't bother with uid and gid with Docker, so the generated files will be owned by root.

Comment by gvdhoorn on 2017-07-06:
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.

Comment by gvdhoorn on 2017-07-06:
This same procedure should work for other robots as well, just make sure to select a proper iktype for those models (instead of translationyaxisangle4d).

Comment by Bas on 2017-07-06:
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!

Comment by gvdhoorn on 2017-07-06:
I don't think it's changed too much, but the most recent version of the tutorial can be found here.

Comment by hamzamerzic on 2017-12-07:
To add to this - in case you don't go with the Docker image, make sure you don't have mpmath installed.

Comment by yijiangh on 2018-03-17:
Complementing gvdhoorn's answer, I've posted an exmaple xml file here: https://answers.ros.org/question/196753/generating-ikfast-plugin-for-5-dof-robot/?answer=285707#post-id-285707

Comment by hamzamerzic on 2018-03-17:
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: https://www.hamzamerzic.info/ikfast_generator/

Comment by lv on 2019-10-28:
Hi, I'm also generating an ikfast plugin for 3 DOF arm, after running command "docker run -it --rm -v ...", I got the result as follows.

openravepy.databases.inversekinematics: RunFromParser, testing the success rate of robot /ikfast/wrapper.xml 2019-10-29 00:32:27,979 openrave [WARN] [plugindatabase.h:577 InterfaceBasePtr OpenRAVE::RaveDatabase::Create] Failed to create name fcl_, interface collisionchecker 2019-10-29 00:32:27,987 openrave [WARN] [kinbody.cpp:1504 KinBody::SetDOFValues] dof 0 value is not in limits 0.000000e+00<5.260000e-01 openravepy.databases.inversekinematics: testik, success rate: 1.000000, wrong solutions: 0.000000, no solutions: 0.000000, missing solution: 0.997000 what does missing solution mean, is it OK?

Comment by gvdhoorn on 2019-11-04:
Missing solution means that for some IK queries, the solver could not return a solution. In your specific case the solver could not solve the IK query in 0.3 percent of the requests. So for 1000 requests, 3 would go unanswered.


Rosanswers logo

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]

Originally posted by lukicdarkoo with karma: 486 on 2020-11-19

This answer was NOT ACCEPTED on the original site

Post score: 1


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.