GithubHelp home page GithubHelp logo

andyzeng / ikfastpy Goto Github PK

View Code? Open in Web Editor NEW
216.0 8.0 66.0 9.04 MB

Python wrapper over OpenRave's IKFast inverse kinematics solver for a UR5 robot arm.

Python 0.54% C++ 99.46%
robotics motion-planning inverse-kinematics forward-kinematics trajectory-optimization universal-robots artificial-intelligence openrave ikfast

ikfastpy's Introduction

IKFastPy - UR5 IKFast Python Package

This is a lightweight Python wrapper over OpenRave's generated IKFast C++ executables for the UR5 robot arm (e-series XML files included). IKFast "analytically solves robot inverse kinematics equations and generates optimized C++ files" for fast runtime speeds (more about IKFast here). IKFast can be used in tandem with URScript speedj commands on UR robot arms for real-time motion planning, which was used to create the visual servoing demo shown on the right (part of an ongoing project on closed-loop grasping with deep learning). Why speedj? See this UR performance analysis report.

Note: this package can be easily modified to support other robot arms.

Files

  • ur5.robot.xml - a custom OpenRave XML file describing the kinematics of the UR5 robot arm. Modify this if you change the arm or tool center point (TCP) position.
  • ikfast61.cpp - C++ code at the heart of IKFast, generated by OpenRave using ur5.robot.xml. No need to modify this.
  • ikfast.h - a C++ header file necessary for compiling ikfast61.cpp. No need to modify this.
  • ikfast_wrapper.cpp - a C++ wrapper around ikfast61.cpp. Includes forward kinematics in addition to the inverse kinematics provided by ikfast61.cpp. Modify this to change how FK and IK results are passed to your code.
  • ikfastpy.pyx, Kinematics.hpp, setup.py - Cython code to link C++ with Python.
  • demo.py - a demo in Python to test FK and IK calls to IKFast.

Installation

This implementation requires the following dependencies (tested on Ubuntu 16.04.4 LTS):

  • NumPy, Cython. You can quickly install/update these dependencies by running the following:
    pip install --user numpy Cython

Quick Start

  1. Checkout this repository and compile the Cython wrapper:
    git clone https://github.com/andyzeng/ikfastpy.git
    cd ikfastpy
    python setup.py build_ext --inplace
  2. Run the demo in Python to test FK and IK calls to IKFast:
    python demo.py

Important: ensure all rotation matrices are valid before feeding into IKFast, otherwise no IK solution will be detected. R is a rotation matrix if and only if R is orthogonal, i.e. RRT = RTR = I, and det(R) = 1.

Note: IKFast does not return solutions for singularities. In most cases, an approximate IK solution can be found for singularities by slightly perturbing the target end effector pose before re-computing IK solutions.

Modifying Robot Kinematics with OpenRave

  1. Download and install OpenRave. See these installation instructions for Ubuntu 16.04.

  2. Modify the kinematics of the arm or TCP position (link6) by changing ur5.robot.xml respectively. You can find a description of the OpenRave XML file format here.

  3. (Optional) Debug the kinematics using OpenRave's viewer:

    openrave ur5.robot.xml
  4. (Optional) Check the links in your file:

    openrave-robot.py ur5.robot.xml --info links
  5. Use OpenRave to re-generate the IKFast C++ code ikfast61.cpp.

    python `openrave-config --python-dir`/openravepy/_openravepy_/ikfast.py --robot=ur5.robot.xml --iktype=transform6d --baselink=0 --eelink=6 --savefile=ikfast61.cpp --maxcasedepth 1

Citation

If you find IKFast useful, please cite OpenRave:

@phdthesis{diankov_thesis,
  author = "Rosen Diankov",
  title = "Automated Construction of Robotic Manipulation Programs",
  school = "Carnegie Mellon University, Robotics Institute",
  month = "August",
  year = "2010",
  number= "CMU-RI-TR-10-29",
  url={http://www.programmingvision.com/rosen_diankov_thesis.pdf},
}

This module was also a part of Visual Pushing and Grasping. If you find it useful in your work, please consider citing:

@inproceedings{zeng2018learning,
  title={Learning Synergies between Pushing and Grasping with Self-supervised Deep Reinforcement Learning},
  author={Zeng, Andy and Song, Shuran and Welker, Stefan and Lee, Johnny and Rodriguez, Alberto and Funkhouser, Thomas},
  booktitle={IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS)},
  year={2018}
}

ikfastpy's People

Contributors

andyzeng avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ikfastpy's Issues

The ikfastpy can not get the correct ur5 rotation matrix in the world frame.

Thank you for your work.
we want to use your code to creat the solutions for ur5. But we get different solutions when we calculate the rotation matrixs between from ROS and your code.
for examp,we get the rotation matrixs from quaternion in ros:
[ 9.44e-05 1 9.762e-05 -1.0915e-01
-1.56e-04 9.76e-05 -9.999e-01 6.04687e-01
-1 9.440e-05 1.5637e-04 4.318e-01 ]

but your code from jiont angle is :
rotation matrixs:
[ 1 9.746e-05 -9.446e-5 -1.0915e-01
9.76e-05 -9.999e-01 1.56e-04 6.04687e-01

  • 9.440e-05 -1.56e-04 -1 4.318e-01]
    We can see the two rotation matrixs have same position information,but the rotation part seem to be in other coordinate system

an example for visual servoing

Hi @andyzeng, many thanks for open-sourcing this great repo for UR5.

In the README, you mentioned that IKFast can be used with speedj command for real-time visual servoing. I am wondering do you have a example code for that? How do you get the Jacobian of the UR5?

Thank you very much.

Unknown reason for failure to get solutions

Hi,
I found that the wrapper was doing something wierd.
My regenerated robot model is pretty much the same as it is in the repo, expect for the last link translation. I changed that from 0.0823 to 0.3

The issue is:
For tatget rotation configuration that's aligned with the initial frame, the solver seems to fail no matter how. I tried a feasible configuration close to that and the inverse could work. Please check the code below.

Python 3.6.8 (default, Dec 24 2018, 19:24:27) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from ikfastpy import ikfastpy
>>> import numpy as np
>>> kin = ikfastpy.PyKinematics()
>>> p = np.array([0,-2.2, 1.38, -0.723, 1.45, 1.51])
>>> ee_pose = np.array(kin.forward(p)).reshape(3,4)
>>> ee_pose
array([[ 0.9979704 ,  0.05739251, -0.02759018, -0.12037876],
       [-0.06031614,  0.99087894, -0.12050273, -0.14530082],
       [ 0.02042257,  0.12192228,  0.99232954,  1.0146302 ]])
>>> kin.inverse(ee_pose.reshape(-1).tolist())
[-1.597476601600647, -2.515026330947876, 1.3043287992477417, -0.4816295802593231, 1.5464282035827637, 3.110640048980713, -1.597476601600647, -2.240016460418701, 1.3455054759979248, 2.3437767028808594, -1.5464282035827637, -0.030952485278248787, 2.2614331740555826e-08, -2.200000047683716, 1.3799999952316284, -0.7229999899864197, 1.4500000476837158, 1.5099999904632568, 2.261408127424147e-08, -1.8565380573272705, 1.2691690921783447, 2.1859614849090576, -1.4500000476837158, -1.6315926313400269, -1.597476601600647, -1.2718806266784668, -1.3043287992477417, 0.8838823437690735, 1.5464282035827637, 3.110640048980713, 2.2614297989775878e-08, -0.6463527083396912, -1.2691690921783447, -2.769070863723755, -1.4500000476837158, -1.6315926313400269, -1.597476601600647, -0.9583459496498108, -1.3455054759979248, -2.5300683975219727, -1.5464282035827637, -0.030952485278248787, 2.26142358172865e-08, -0.8861240148544312, -1.3799999952316284, 0.7231239676475525, 1.4500000476837158, 1.5099999904632568]

However if I change the rotation frame to identity, the inverse fails. I double checked that this configuration is not at singularity.

>>> ee_pose[:,:3] = np.eye(3)
>>> ee_pose
array([[ 1.        ,  0.        ,  0.        , -0.12037876],
       [ 0.        ,  1.        ,  0.        , -0.14530082],
       [ 0.        ,  0.        ,  1.        ,  1.0146302 ]])
>>> kin.inverse(ee_pose.reshape(-1).tolist())
Error: (inverse kinematics) failed to get ik solution
[]

Goal tolerance setting

Hello, is there any way to change the IK accuracy in this setup?

I have created Translation3D solver only for the wrist part of the UR5e. I can successfully compute forward and inverse kinematics. But the joint (or goal) tolerances are too small that most of the time I cannot get any valid solutions.

For instance ee_pose_test returns a valid solution whereas ee_pose_test2 does not.

ee_pose_test = np.array([[ 1., 0., 0., 0.1000000015],
[ 0., 1., 0., 0.22650042],
[ 0., 1., 0., 0.00998334]])

ee_pose_test2 = np.array([[ 1., 0., 0., 0.1000000],
[ 0., 1., 0., 0.22650],
[ 0., 1., 0., 0.00998]])

I was wondering if is there any chance that I can set an ε or something that I can reduce the required significant numbers of EE_pose which I use in the IK solver? Something like arm_group.set_goal_joint_tolerance(0.001) in Moveit.

In this link I saw that --accuracy parameter which is used during creating ik.cpp can do something similar. However, it is also stated that to increase this tolerance value may cause bigger problems in the solver.

Any suggestions?

Can we make same wrapper for C++ ?

Hi all,
I want to find FK and IK of given pose data since my project is in C++ language, thus I want to make cpp wrapper on ikfast61.cpp. I'm just not sure which file should i use to extend in my wrapper to make it able to work like python wrapper of this repository.
I tried to include ikfast61.cpp file in my cpp wrapper but it gives this error:

/tmp/ccZNJDSH.o: In function `IKSolver::solvedialyticpoly8qep(double const*, double*, int&)':
mywrapper.cpp:(.text._ZN8IKSolver21solvedialyticpoly8qepEPKdPdRi[_ZN8IKSolver21solvedialyticpoly8qepEPKdPdRi]+0x492): undefined reference to `dgetrf_'

Any kind of help will be appreciated. Thank you

NoConvergence: Didn't converge in maxsteps=50 steps, when regenerating ikfast61.cpp

Hi @andyzeng,
Thanks for sharing this awesome work!
I was trying to modify the robot configuration and regenerate the ikfast61.cpp file following the instructions you gave. I got a NoConvergence error and it remains even when I test it without modifying the ur.robot.xml. Any suggestions on how to debug this issue? Appreciate it!

Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/openravepy/_openravepy_/ikfast.py", line 9521, in <module>
    chaintree = solver.generateIkSolver(options.baselink,options.eelink,options.freeindices,solvefn=solvefn)
  File "/usr/local/lib/python2.7/dist-packages/openravepy/_openravepy_/ikfast.py", line 2281, in generateIkSolver
    chaintree = solvefn(self, LinksRaw, jointvars, isolvejointvars)
  File "/usr/local/lib/python2.7/dist-packages/openravepy/_openravepy_/ikfast.py", line 2936, in solveFullIK_6D
    tree = self.solveFullIK_6DGeneral(T0links, T1links, solvejointvars, endbranchtree, usesolvers=1)
  File "/usr/local/lib/python2.7/dist-packages/openravepy/_openravepy_/ikfast.py", line 3271, in solveFullIK_6DGeneral
    leftovertree = self.SolveAllEquations(AllEquationsExtra,curvars=curvars,othersolvedvars = self.freejointvars+usedvars,solsubs = solsubs,endbranchtree=origendbranchtree)
  File "/usr/local/lib/python2.7/dist-packages/openravepy/_openravepy_/ikfast.py", line 6848, in SolveAllEquations
    return self.AddSolution(solutions,AllEquations,curvars,othersolvedvars,solsubs,endbranchtree,currentcases=currentcases, currentcasesubs=currentcasesubs, unknownvars=unknownvars)
  File "/usr/local/lib/python2.7/dist-packages/openravepy/_openravepy_/ikfast.py", line 7511, in AddSolution
    newtree = self.SolveAllEquations(NewEquationsClean,curvars,othersolvedvars,solsubs,endbranchtree,currentcases=newcases, currentcasesubs=newcasesubs, unknownvars=unknownvars)
  File "/usr/local/lib/python2.7/dist-packages/openravepy/_openravepy_/ikfast.py", line 6848, in SolveAllEquations
    return self.AddSolution(solutions,AllEquations,curvars,othersolvedvars,solsubs,endbranchtree,currentcases=currentcases, currentcasesubs=currentcasesubs, unknownvars=unknownvars)
  File "/usr/local/lib/python2.7/dist-packages/openravepy/_openravepy_/ikfast.py", line 7213, in AddSolution
    nextsolutions[var] = self.SolveAllEquations(AllEquations,curvars=newvars,othersolvedvars=othersolvedvars+[var],solsubs=solsubs+self.Variable(var).subs,endbranchtree=endbranchtree,currentcases=currentcases, currentcasesubs=currentcasesubs, unknownvars=unknownvars)
  File "/usr/local/lib/python2.7/dist-packages/openravepy/_openravepy_/ikfast.py", line 6828, in SolveAllEquations
    rawsolutions=self.SolvePairVariables(raweqns,var0,var1,othersolvedvars,unknownvars=curvars+unknownvars)
  File "/usr/local/lib/python2.7/dist-packages/openravepy/_openravepy_/ikfast.py", line 8955, in SolvePairVariables
    return self.SolvePairVariablesHalfAngle(raweqns,var0,var1,othersolvedvars)
  File "/usr/local/lib/python2.7/dist-packages/openravepy/_openravepy_/ikfast.py", line 7740, in SolvePairVariablesHalfAngle
    possiblefinaleq = self.checkFinalEquation(Poly(Malldet,leftvar),subs)
  File "/usr/local/lib/python2.7/dist-packages/openravepy/_openravepy_/ikfast.py", line 8154, in checkFinalEquation
    roots = mpmath.polyroots(numpy.array(numpy.array(coeffs),numpy.float64))
  File "/usr/lib/python2.7/dist-packages/mpmath/calculus/polynomials.py", line 189, in polyroots
    % maxsteps)
mpmath.libmp.libhyper.NoConvergence: Didn't converge in maxsteps=50 steps.

Get Poses of all joints

How can I use ikfastpy to get the poses of all joints?

ee_pose = np.asarray(ee_pose).reshape(3,4) -> gives me just the endefector ...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.