Giter Club home page Giter Club logo

bio_ik's Introduction

bio_ik

Disclaimer

This repository provides a BSD-licensed standalone implementation of a variety of optimization methods to efficiently solve generalized inverse kinematics problems.

The whole module was implemented by Philipp Ruppel as part of his Master Thesis.

For a C++-based reimplementation of the original "BioIK" algorithm, as originally sold in the Unity store, you can use the non-default mode bio1. The default mode bio2_memetic shares no code with this implementation, was shown to outperform it in terms of success rate, precision and efficiency, and is actually usable for precise robotic applications [4].

Installation and Setup

You will need ROS version Indigo or newer (wiki.ros.org). The software was developed on Ubuntu Linux 16.04 LTS with ROS Kinetic, but has also been tested on Ubuntu Linux 14.04 LTS with ROS Indigo. Newer versions of ROS should work, but may need some adaptation. See below for version specific instructions.

  • Download the bio_ik package and unpack into your catkin workspace.

  • Run catkin_make to compile your workspace:

      roscd
      cd src
      git clone https://github.com/TAMS-Group/bio_ik.git
      roscd
      catkin_make
    
  • Configure Moveit to use bio_ik as the kinematics solver (see next section).

  • Use Moveit to plan and execute motions or use your own code together with move_group node to move your robot.

  • As usual, the public API is specified in the public header files for the bio_ik package, located in the include/bio_ik subdirectory; the sources including a few private header files are in the src subdirectory.

Basic Usage

For ease of use and compatibility with existing code, the bio_ik algorithm is encapsulated as a Moveit kinematics plugin. Therefore, bio_ik can be used as a direct replacement of the default Orocos/KDL-based IK solver. Given the name of an end-effector and a 6-DOF target pose, bio_ik will search a valid robot joint configuration that reaches the given target.

In our tests (see below), both in terms of success rate and solution time, bio_ik regularly outperformed the Orocos [1] solver and is competitive with trac-ik [2]. The bio_ik algorithm can also be used for high-DOF system like robot snakes, and it will automatically converge to the best approximate solutions for low-DOF arms where some target poses are not reachable exactly.

While you can write the Moveit configuration files by hand, the easiest way is to run the Moveit setup assistant for your robot, and then to select bio_ik as the IK solver when configuring the end effectors. Once configured, the solver can be called using the standard Moveit API or used interactively from rviz using the MotionPlanning GUI plugin.

  • Make sure that you have a URDF (or xacro) model for your robot.

  • Run the moveit setup assistant to create the Moveit configuration files:

    rosrun moveit_setup_assistant moveit_setup_assistant
    
    
  • The setup assistant automatically searches for all available IK solver plugins in your workspace. Therefore, you can just select select bio_ik as the IK solver from the drop-down list for every end effector and then configure the kinematics parameters, namely the default position accuracy (meters) and the timeout (in seconds). For typical 6-DOF or 7-DOF arms, an accuracy of 0.001 m (or smaller) and a timeout of 1 msec should be ok. More complex robots might need a longer timeout.

  • Generate the moveit configuration files from the setup assistant. Of course, you can also edit the config/kinematics.yaml configuration file with your favorite text editor. For example, a configuration for the PR2 robot might look like this:

      # example kinematics.yaml for the PR2 robot
      right_arm:
        # kinematics_solver: kdl_kinematics_plugin/KDLKinematicsPlugin
        # kinematics_solver_attempts: 1
        kinematics_solver: bio_ik/BioIKKinematicsPlugin
        kinematics_solver_search_resolution: 0.005
        kinematics_solver_timeout: 0.005
        kinematics_solver_attempts: 1
      left_arm:
        kinematics_solver: bio_ik/BioIKKinematicsPlugin
        kinematics_solver_search_resolution: 0.005
        kinematics_solver_timeout: 0.005
        kinematics_solver_attempts: 1
      all:
        kinematics_solver: bio_ik/BioIKKinematicsPlugin
        kinematics_solver_search_resolution: 0.005
        kinematics_solver_timeout: 0.02
        kinematics_solver_attempts: 1
    
      # optional bio_ik configuration parameters
      #  center_joints_weight: 1
      #  minimal_displacement_weight: 1
      #  avoid_joint_limits_weight: 1
    
  • For a first test, run the Moveit-created demo launch. Once rviz is running, enable the motion planning plugin, then select one of the end effectors of you robot. Rviz should show an 6-D (position and orientation) interactive marker for the selected end-effector(s). Move the interactive marker and watch bio_ik calculating poses for your robot.

    If you also installed the bio_ik demo (see below), you should be able to run one of the predefined demos:

      roslaunch pr2_bioik_moveit demo.launch
      roslaunch pr2_bioik_moveit valve.launch
      roslaunch pr2_bioik_moveit dance.launch
    
  • You are now ready to use bio_ik from your C/C++ and Python programs, using the standard Moveit API. To explicitly request an IK solution in C++:

      robot_model_loader::RobotModelLoader robot_model_loader(robot);
    
      auto robot_model = robot_model_loader.getModel();
      auto joint_model_group = robot_model->getJointModelGroup(group);
      auto tip_names = joint_model_group->getSolverInstance()->getTipFrames();
    
      kinematics::KinematicsQueryOptions opts;
      opts.return_approximate_solution = true; // optional
    
      robot_state::RobotState robot_state_ik(robot_model);
    
      // traditional "basic" bio_ik usage. The end-effector goal poses
      // and end-effector link names are passed into the setFromIK()
      // call. The KinematicsQueryOptions are empty.
      //
      bool ok = robot_state_ik.setFromIK(
                  joint_model_group, // joints to be used for IK
                  tip_transforms,    // multiple end-effector goal poses
                  tip_names,         // names of the end-effector links
                  attempts, timeout, // solver attempts and timeout
                  moveit::core::GroupStateValidityCallbackFn(),
                  opts               // mostly empty
                );
    

Advanced Usage

For many robot applications, it is essential to specify more than just a single end-effector pose. Typical examples include

  • redundancy resolution (e.g. 7-DOF arm)
  • two-arm manipulation tasks on two-arm robots (e.g. Baxter)
  • multi end-effector tasks with shared kinematic links
  • grasping and manipulation tasks with multi-finger hands
  • full-body motion on humanoid robots
  • reaching tasks with additional constraints (e.g. shoulder position)
  • incremental tool motions without robot arm configuration changes
  • and many more

In bio_ik, such tasks are specified as a combination of multiple individual goals.
The algorithm then tries to find a robot configuration that fulfills all given goals simultaneously by minimizing a quadratic error function built from the weighted individual goals. While the current Moveit API does not support multiple-goals tasks directly, it provides the KinematicQueryOptions class. Therefore, bio_ik simply provides a set of predefined motion goals, and a combination of the user-specified goals is passed via Moveit to the IK solver. No API changes are required in Moveit, but using the IK solver now consists passing the weighted goals via the KinematicQueryOptions. The predefined goals include:

  • PoseGoal: a full 6-DOF robot pose
  • PositionGoal: a 3-DOF (x,y,z) position
  • OrientationGoal: a 3-DOF orientation, encoded as a quaternion (qx,qy,qz,qw)
  • LookAtGoal: a 3-DOF (x,y,z) position intended as a looking direction for a camera or robot head
  • JointGoal: a set of joint angles, e.g. to specify a
  • FunctionGoal: an arbitrary function of the robot joint values, e.g. to model underactuated joints or mimic joints
  • and several more

To solve a motion problem on your robot, the trick now is to construct a suitable combination of individual goals.

PR2 turning a valve

In the following example, we want to grasp and then slowly turn a valve wheel with the left and right gripers of the PR2 robot:

  bio_ik::BioIKKinematicsQueryOptions ik_options;
  ik_options.replace = true;
  ik_options.return_approximate_solution = true;

  auto* ll_goal = new bio_ik::PoseGoal();
  auto* lr_goal = new bio_ik::PoseGoal();
  auto* rl_goal = new bio_ik::PoseGoal();
  auto* rr_goal = new bio_ik::PoseGoal();
  ll_goal->setLinkName("l_gripper_l_finger_tip_link");
  lr_goal->setLinkName("l_gripper_r_finger_tip_link");
  rl_goal->setLinkName("r_gripper_l_finger_tip_link");
  rr_goal->setLinkName("r_gripper_r_finger_tip_link");
  ik_options.goals.emplace_back(ll_goal);
  ik_options.goals.emplace_back(lr_goal);
  ik_options.goals.emplace_back(rl_goal);
  ik_options.goals.emplace_back(rr_goal);

We also set a couple of secondary goals. First, we want that the head of the PR2 looks at the center of the valve. Second, we want to avoid joint-limits on all joints, if possible. Third, we want that IK solutions are as close as possible to the previous joint configuration, meaning small and efficient motions. This is handled by adding the MinimalDisplacementGoal. Fourth, we want to avoid torso lift motions, which are very slow on the PR2. All of this is specified easily:

   auto* lookat_goal = new bio_ik::LookAtGoal();
   lookat_goal->setLinkName("sensor_mount_link");
   ik_options.goals.emplace_back(lookat_goal);

   auto* avoid_joint_limits_goal = new bio_ik::AvoidJointLimitsGoal();
   ik_options.goals.emplace_back(avoid_joint_limits_goal);

   auto* minimal_displacement_goal = new bio_ik::MinimalDisplacementGoal();
   ik_options.goals.emplace_back(minimal_displacement_goal);

   auto* torso_goal = new bio_ik::PositionGoal();
   torso_goal->setLinkName("torso_lift_link");
   torso_goal->setWeight(1);
   torso_goal->setPosition(tf::Vector3( -0.05, 0, 1.0 ));
   ik_options.goals.emplace_back(torso_goal);

For the actual turning motion, we calculate a set of required gripper poses in a loop:

  for(int i = 0; ; i++) {
      tf::Vector3 center(0.7, 0, 1);

      double t = i * 0.1;
      double r = 0.1;
      double a = sin(t) * 1;
      double dx = fmin(0.0, cos(t) * -0.1);
      double dy = cos(a) * r;
      double dz = sin(a) * r;

      tf::Vector3 dl(dx, +dy, +dz);
      tf::Vector3 dr(dx, -dy, -dz);
      tf::Vector3 dg = tf::Vector3(0, cos(a), sin(a)) * (0.025 + fmin(0.025, fmax(0.0, cos(t) * 0.1)));

      ll_goal->setPosition(center + dl + dg);
      lr_goal->setPosition(center + dl - dg);
      rl_goal->setPosition(center + dr + dg);
      rr_goal->setPosition(center + dr - dg);

      double ro = 0;
      ll_goal->setOrientation(tf::Quaternion(tf::Vector3(1, 0, 0), a + ro));
      lr_goal->setOrientation(tf::Quaternion(tf::Vector3(1, 0, 0), a + ro));
      rl_goal->setOrientation(tf::Quaternion(tf::Vector3(1, 0, 0), a + ro));
      rr_goal->setOrientation(tf::Quaternion(tf::Vector3(1, 0, 0), a + ro));

      lookat_goal->setAxis(tf::Vector3(1, 0, 0));
      lookat_goal->setTarget(rr_goal->getPosition());

      // "advanced" bio_ik usage. The call parameters for the end-effector
      // poses and end-effector link names are left empty; instead the
      // requested goals and weights are passed via the ik_options object.
      //
      robot_state.setFromIK(
                    joint_model_group,           // active PR2 joints
                    EigenSTL::vector_Affine3d(), // no explicit poses here
                    std::vector<std::string>(),  // no end effector links here
                    0, 0.0,                      // take values from YAML file
                    moveit::core::GroupStateValidityCallbackFn(),
                    ik_options       // four gripper goals and secondary goals
                  );

      ... // check solution validity and actually move the robot
  }

When you execute the code, the PR2 will reach for the valve wheel and turn it. Every once in a while it can't reach the valve with its current arm configuration and will regrasp the wheel.

See [3] and [4] for more examples.

Local vs. Global Optimization, Redundancy Resolution, Cartesian Jogging

BioIK has been developed to efficiently find good solutions for non-convex inverse kinematics problems with multiple goals and local minima. However, for some applications, this can lead to unintuitive results. If there are multiple possible solutions to a given IK problem, and if the user has not explicitly specified which one to choose, a result may be selected randomly from the set of all valid solutions. When incrementally tracking a cartesian path, this can result in unwanted jumps, shaking, etc. To incrementally generate a smooth trajectory using BioIK, the desired behaviour should be specified explicitly, which can be done in two ways.

Disabling Global Optimization

BioIK offers a number of different solvers, including global optimizers and local optimizers. By default, BioIK uses a memetic global optimizer (bio2_memetic). A different solver class can be selected by setting the mode parameter in the kinematics.yaml file of your MoveIt robot configuration.

Example:

all:
  kinematics_solver: bio_ik/BioIKKinematicsPlugin
  kinematics_solver_search_resolution: 0.005
  kinematics_solver_timeout: 0.02
  kinematics_solver_attempts: 1
  mode: gd_c

Currently available local optimizers:

gd, gd_2, gd_4, gd_8
gd_r, gd_r_2, gd_r_4, gd_r_8
gd_c, gd_c_2, gd_c_4, gd_c_8
jac, jac_2, jac_4, jac_8

Naming convention: <solver type>_[<variant>_]<number of threads>

Notes:

  • The gd_* solvers support arbitrary goal types.
  • The jac_* solvers only support pose goals but might in theory be more stable in some cases.
  • Relative performance depends on the application (it's probably best if you try it yourself for your particular robot and problem types).
  • During our tests, the gd_c variants usually outperformed the other local solvers.
  • For incremental tracking, a single-threaded variant without restarts is probably best suited (gd_c, gd, or jac).
  • You can also create different MoveIt move groups with different solver types. If you now want to plan a cartesian trajectory from end effector pose A to end effector pose B, you can use a move group with a global optimizer to find a matching initial pose for end effector pose A and a different move group with a local optimizer for incrementally generating a smooth cartesian trajectory from A to B.

Regularization

You can force a global optimizer to return a local minimum through regularization.

  • For the specific case of incremental robot motions (aka jogging), the simplest solution is to specify both a PoseGoal and the special RegularizationGoal, which tries to keep the joint-space IK solution as close as possible to the given robot seed configuration. Typically you would use a high weight for the PoseGoal and a smaller weight to the regularizer.

  • You can also add a MinimalDisplacementGoal instead of the RegularizationGoal. Both goals try to keep the IK solution close to the current/seed robot state, but differ slightly in the handling of fast and slow robot joints (e.g. the PR2 has fast arm joints and a rather slow torso lift joint). You might want to play with both goals to see which one better matches your needs.

  • Some industrial robot controllers on 7-DOF arms behave as if working on a 6-DOF arm with one extra joint. Typically, the value of the extra joint can be specified, and an IK solution is then searched for the remaining six joints. This behaviour can be achieved in bio_ik by combining a PoseGoal for the end-effector with a JointPositionGoal for one (any one) of the robot joints.

  • Another useful trick is trying to keep the robot joints centered, as this will allow robot (joint) motions in both directions. Just combine the PoseGoal with a CenterJointsGoal, and optionally also a RegularizationGaol.

  • You can also combine regularization with a local gd_* solver.

How it works

The bio_ik solver is based on a memetic algorithm that combines gradient-based optimization with genetic and particle swarm optimization.

Internally, vectors of all robot joint values are used to encode different intermediate solutions (the genotype of the genetic algorithm). During the optimization, joint values are always checked against the active lower and upper joint limits, so that only valid robot configurations are generated.

To calculate the fitness of individuals, the cumulative error over all given individual goals is calculated. Any individual with zero error is an exact solution for the IK problem, while individuals with small error correspond to approximate solutions.

Individuals are sorted by their fitness, and gradient-based optimization is tried on the best few configuration, resulting in fast convergence and good performance for many problems. If no solution is found from the gradient-based optimization, new individuals are created by a set of mutation and recombination operators, resulting in good search-space exploration.

See [3] and [4] for more details. See [5] and [6] for an in-depth explanation of an earlier evolutionary algorithm for animating video game characters.

Running the Self-Tests

We have tested bio_ik on many different robot arms, both using the tranditional single end-effector API and the advanced multi end-effector API based on the KinematicsQueryOptions.

One simple selftest consists of generating random valid robot configurations, running forward kinematics to calculate the resulting end-effector pose, and the querying the IK plugin to find a suitable robot joint configuration. Success is then checked by running forrward kinematics again and checking that the end-effector pose for the generated IK solution matches the target pose. This approach can be run easily for thousands or millions of random poses, samples the full workspace of the robot, and allows to quickly generate success-rate and solution-time estimates for the selected IK solver.

Of course, running the tests requires installing the corresponding robot models and adds a lot of dependencies. Therefore, those tests are not included in the standard bio_ik package, but are packaged separately.

For convenience, we provide the pr2_bioik_moveit package, which also includes a few bio_ik demos for the PR2 service robot. These are kinematics only demos; but of course you can also try running the demos on the real robot (if you have one) or the Gazebo simulator (if you installed Gazebo).

Simply clone the PR2 description package (inside pr2_common) and the pr2_bioik_moveit package into your catkin workspace:

  roscd
  cd src
  git clone https://github.com/PR2/pr2_common.git
  git clone https://github.com/TAMS-Group/bioik_pr2.git
  catkin_make

For the FK-IK-FK performance test, please run

roslaunch pr2_bioik_moveit env_pr2.launch
roslaunch pr2_bioik_moveit test_fk_ik.launch
... // wait for test completion and results summary

References

  1. Orocos Kinematics and Dynamics, http://www.orocos.org

  2. P. Beeson and B. Ames, TRAC-IK: An open-source library for improved solving of generic inverse kinematics, Proceedings of the IEEE RAS Humanoids Conference, Seoul, Korea, November 2015.

  3. Philipp Ruppel, Norman Hendrich, Sebastian Starke, Jianwei Zhang, Cost Functions to Specify Full-Body Motion and Multi-Goal Manipulation Tasks, IEEE International Conference on Robotics and Automation, (ICRA-2018), Brisbane, Australia. DOI: 10.1109/ICRA.2018.8460799

  4. Philipp Ruppel, Performance optimization and implementation of evolutionary inverse kinematics in ROS, MSc thesis, University of Hamburg, 2017 PDF

  5. Sebastian Starke, Norman Hendrich, Jianwei Zhang, A Memetic Evolutionary Algorithm for Real-Time Articulated Kinematic Motion, IEEE Intl. Congress on Evolutionary Computation (CEC-2017), p.2437-2479, June 4-8, 2017, San Sebastian, Spain. DOI: 10.1109/CEC.2017.7969605

  6. Sebastian Starke, Norman Hendrich, Dennis Krupke, Jianwei Zhang, Multi-Objective Evolutionary Optimisation for Inverse Kinematics on Highly Articulated and Humanoid Robots, IEEE Intl. Conference on Intelligent Robots and Systems (IROS-2017), September 24-28, 2017, Vancouver, Canada

Links

bio_ik's People

Contributors

dudasdavid avatar flova avatar henningkayser avatar javajeremy avatar jgueldenstein avatar jspricke avatar lianghongzhuo avatar normanhendrich avatar philipp1234 avatar rhaschke avatar timonegk avatar v4hn 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bio_ik's Issues

Get error when use computeCartesianPath()

Environment: ros-kinetic
I can success to use bio_ik by setFromIK(), but when I use computeCartesianPath(), I get the error info Returning dirty link transforms.

Use angle between quaternions in OrientationGoal?

Currently the orientation goal looks like this:

    virtual double evaluate(const GoalContext& context) const
    {
        // return getOrientation().distance2(context.getLinkFrame().getOrientation());
        // return (getOrientation() - getOrientation().nearest(context.getLinkFrame().getOrientation())).length2();
        return fmin((getOrientation() - context.getLinkFrame().getOrientation()).length2(), (getOrientation() + context.getLinkFrame().getOrientation()).length2());
        /*return
            (getOrientation() - context.getLinkFrame().getOrientation()).length2() *
            (getOrientation() + context.getLinkFrame().getOrientation()).length2() * 0.5;*/
    }

I don't know a ton about quaternions but this seems like a nonlinear function so it might behave kind of funky: (getOrientation() - context.getLinkFrame().getOrientation()).length2()

Would it be better to use the angle between the quaternions? That would increase in a nice, linear fashion from 0 to pi.

angle

https://math.stackexchange.com/a/90098/448782

Touch Goal: How to use it?

Hey!

I am trying to use the touch goal and there is lots of element needed to make it work.
I am not that familiar with moveit to understand all the inputs needed for the touch goal.
Could you explain what inputs are needed for the touch goal?

Thanks :)

Building tests fails

[ 91%] Building CXX object CMakeFiles/utest.dir/test/utest.cpp.o
/vol/sandbox/ros/src/bio_ik/test/utest.cpp:6:10: fatal error: ../src/frame.h: No such file or directory
#include "../src/frame.h"

Reduce logging

Currently, BioIK logs ikbio bio ik init <node name> for each move group. This is neither helpful nor necessary. It would be nice to reduce/remove the logging, for example by moving the #define ENABLE_LOGGING in src/utils.h to the CMakeLists to optionally enable debug logging, or by switching to ROS loggers.

add_dependencies called with incorrect number of arguments

Hi, I am trying to install bio_ik using the following steps
git clone https://github.com/TAMS-Group/bio_ik.git
catkin_make

However, I am getting this error

CMake Error at /opt/ros/noetic/share/dynamic_reconfigure/cmake/dynamic_reconfigure-macros.cmake:84 (add_custom_target):
  add_custom_target cannot create target "moveit_ros_manipulation_gencfg"
  because another target with the same name already exists.  The existing
  target is a custom target created in source directory
  "/home/akumar/tular_servo_ws/src/xarm_ros/tularm_tracking".  See
  documentation for policy CMP0002 for more details.
Call Stack (most recent call first):
  moveit/moveit_ros/manipulation/CMakeLists.txt:21 (generate_dynamic_reconfigure_options)


CMake Error at moveit/moveit_ros/manipulation/pick_place/CMakeLists.txt:17 (add_dependencies):
  add_dependencies called with incorrect number of arguments

I have cloned github repo of moveit https://github.com/ros-planning/moveit. I tried the same with no moveit and there it worked.
Any help would be much appreciated.

Migrate bio_ik to ros-planning

We have discussed in the past already several times if it would make sense to transfer the bio_ik repo to ros-planning.
There are several changes in the making (ROS 2 support, singularity avoidance, possibly Servo integration) that would require extra maintenance in the future and I could imagine that @v4hn might appreciate some help there from the other MoveIt maintainers.

What do you think?

Samples are generated in two tight clusters

I don't know if this is a bug or not, but it seemed odd and I thought I should share it.

In the course of developing a custom goal, we printed out the pose of the context.getLinkFrame() in the evaluate function. Each time the pose sampler is run, there are 66 samples printed, and they form two very tight clusters. For the example I have in front of me, there are 46 samples that are within a millimeter in translation and less than 1e-4 radians in orientation, and then the remaining 20 samples form another equally tight cluster that is about a half meter and 180 degrees away.

The pose sampler does successfully find a good pose, so it is working. This just seems strange and possibly inefficient.

Cant find Bio-IK in MoveIt Setup Assistant

Hey,

I cant seem to find the Bio-IK solver in the MoveIt setup assistant. Probably the reason causing this is, that I cant use the catkin_make command, because I build my workspace with catkin build. Do you have any idea for a walkaround?

I would appreciate any help!

Jonas

Issue about tutorial

Hi!

When I followed the tutorial to this step, I found that these two files are missing.

roslaunch pr2_bioik_moveit env_pr2.launch
roslaunch pr2_bioik_moveit test_fk_ik.launch

Have these files been moved to another lib or no longer available?

I am interested in bio_IK and would like to implement it on my robot for a quantitative test, i.e., the FK-IK-FK method you mentioned.

Thanks!

Compilation ARMhf

The package does not natively compile on armhf due to the compiler options for x86.
Setting FUNCTION_MULTIVERSIONING to 0 and removing the following from forward_kinematics.h works.
#include <emmintrin.h>
#include <immintrin.h>
#include <x86intrin.h>

URDF not parsable from python wrapper when bio_ik is find_package'd

The problem

I am using the MoveIt RobotModelLoader to load a URDF from the ros parameter server. The URDF will not be parsed when the following two conditions are fulfilled:

  1. The RobotModelLoader is initialized in a function that is called from python, i.e. in a python module/wrapper
  2. bio_ik is listed as a catkin component in CMakeLists.txt

Reproducible example:

  1. cd catkin_ws/src && catkin create pkg minimal_example
  2. Put the following files in the new catkin package:
CMakeLists.txt
cmake_minimum_required(VERSION 2.8.3)
project(minimal_example)

find_package(catkin REQUIRED COMPONENTS
        roscpp
        bio_ik
        moveit_ros_planning
)

find_package(PythonLibs COMPONENTS Interpreter Development)
find_package(Boost REQUIRED COMPONENTS python)

catkin_package()

include_directories(
        ${catkin_INCLUDE_DIRS}
        ${Boost_INCLUDE_DIRS}
        ${PYTHON_INCLUDE_DIRS}
)

add_library(wrapper SHARED wrapper.cpp)
add_dependencies(wrapper ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(wrapper ${catkin_LIBRARIES} ${Boost_LIBRARIES})
set_target_properties(wrapper PROPERTIES
        PREFIX ""
        LIBRARY_OUTPUT_DIRECTORY ${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_PYTHON_DESTINATION}
)
wrapper.cpp
#include <boost/python.hpp>
#include <moveit/robot_model_loader/robot_model_loader.h>

void start() {
    robot_model_loader::RobotModelLoader rml("robot_description", true);
}

BOOST_PYTHON_MODULE (wrapper) {
  using namespace boost::python;

  def("start", &start);
}
  1. Build the package, source the workspace
  2. Load a urdf, e.g. roslaunch pr2-description upload_pr2.launch
  3. Run the following in python:
from moveit_ros_planning_interface._moveit_roscpp_initializer import roscpp_init
roscpp_init("test", [])
from minimal_example.wrapper import start
start()
Then, a lot of ros errors are raised:
[ERROR] [1613744905.421133198]: Material [Blue] has malformed color rgba values: Unable to parse component [0.0] to a double (while parsing a color value)
[ERROR] [1613744905.421257104]: Material [Blue] color has no rgba
[ERROR] [1613744905.421345652]: Material [Blue] not defined in file
[ERROR] [1613744905.421559337]: Material [Green] has malformed color rgba values: Unable to parse component [0.0] to a double (while parsing a color value)
[ERROR] [1613744905.421679050]: Material [Green] color has no rgba
[ERROR] [1613744905.421736653]: Material [Green] not defined in file
[ERROR] [1613744905.421899605]: Material [Grey] has malformed color rgba values: Unable to parse component [0.7] to a double (while parsing a color value)
[ERROR] [1613744905.421960551]: Material [Grey] color has no rgba
[ERROR] [1613744905.421993995]: Material [Grey] not defined in file
[ERROR] [1613744905.422110530]: Material [Grey2] has malformed color rgba values: Unable to parse component [0.9] to a double (while parsing a color value)
[ERROR] [1613744905.422164421]: Material [Grey2] color has no rgba
[ERROR] [1613744905.422200912]: Material [Grey2] not defined in file
[ERROR] [1613744905.422367720]: Material [Red] has malformed color rgba values: Unable to parse component [0.8] to a double (while parsing a color value)
[ERROR] [1613744905.422454364]: Material [Red] color has no rgba
[ERROR] [1613744905.422525520]: Material [Red] not defined in file
[ERROR] [1613744905.422691867]: Material [White] has malformed color rgba values: Unable to parse component [1.0] to a double (while parsing a color value)
[ERROR] [1613744905.422749125]: Material [White] color has no rgba
[ERROR] [1613744905.422812759]: Material [White] not defined in file
[ERROR] [1613744905.422942299]: Material [Black] has malformed color rgba values: Unable to parse component [0.1] to a double (while parsing a color value)
[ERROR] [1613744905.422995747]: Material [Black] color has no rgba
[ERROR] [1613744905.423060430]: Material [Black] not defined in file
[ERROR] [1613744905.423174719]: Material [LightGrey] has malformed color rgba values: Unable to parse component [0.6] to a double (while parsing a color value)
[ERROR] [1613744905.423210584]: Material [LightGrey] color has no rgba
[ERROR] [1613744905.423251483]: Material [LightGrey] not defined in file
[ERROR] [1613744905.423448811]: Unable to parse component [-0.061] to a double (while parsing a vector value)
[ERROR] [1613744905.423489629]: Could not parse inertial element for Link [base_link]
[ERROR] [1613744905.423588783]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.423626958]: Could not parse inertial element for Link [base_footprint]
[ERROR] [1613744905.423722349]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.423759400]: Could not parse inertial element for Link [base_bellow_link]
[ERROR] [1613744905.423856896]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.423901057]: Could not parse inertial element for Link [base_laser_link]
[ERROR] [1613744905.423998539]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.424035614]: Could not parse inertial element for Link [fl_caster_rotation_link]
[ERROR] [1613744905.424131989]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.424168781]: Could not parse inertial element for Link [fl_caster_l_wheel_link]
[ERROR] [1613744905.424261822]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.424298544]: Could not parse inertial element for Link [fl_caster_r_wheel_link]
[ERROR] [1613744905.424392930]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.424430763]: Could not parse inertial element for Link [fr_caster_rotation_link]
[ERROR] [1613744905.424523717]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.424561717]: Could not parse inertial element for Link [fr_caster_l_wheel_link]
[ERROR] [1613744905.424642766]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.424679720]: Could not parse inertial element for Link [fr_caster_r_wheel_link]
[ERROR] [1613744905.424783002]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.424820717]: Could not parse inertial element for Link [bl_caster_rotation_link]
[ERROR] [1613744905.424900987]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.424937599]: Could not parse inertial element for Link [bl_caster_l_wheel_link]
[ERROR] [1613744905.425029065]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.425064242]: Could not parse inertial element for Link [bl_caster_r_wheel_link]
[ERROR] [1613744905.425139219]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.425177220]: Could not parse inertial element for Link [br_caster_rotation_link]
[ERROR] [1613744905.425269975]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.425306871]: Could not parse inertial element for Link [br_caster_l_wheel_link]
[ERROR] [1613744905.425400131]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.425436585]: Could not parse inertial element for Link [br_caster_r_wheel_link]
[ERROR] [1613744905.425530191]: Unable to parse component [-0.1] to a double (while parsing a vector value)
[ERROR] [1613744905.425567198]: Could not parse inertial element for Link [torso_lift_link]
[ERROR] [1613744905.425667310]: Unable to parse component [-0.0625] to a double (while parsing a vector value)
[ERROR] [1613744905.425704389]: Could not parse inertial element for Link [l_torso_lift_side_plate_link]
[ERROR] [1613744905.425797797]: Unable to parse component [-0.0625] to a double (while parsing a vector value)
[ERROR] [1613744905.425834060]: Could not parse inertial element for Link [r_torso_lift_side_plate_link]
[ERROR] [1613744905.425926920]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.425963485]: Could not parse inertial element for Link [torso_lift_motor_screw_link]
[ERROR] [1613744905.426056790]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.426093051]: Could not parse inertial element for Link [imu_link]
[ERROR] [1613744905.426188788]: Unable to parse component [0.010907] to a double (while parsing a vector value)
[ERROR] [1613744905.426225659]: Could not parse inertial element for Link [head_pan_link]
[ERROR] [1613744905.426319806]: Unable to parse component [0.001716] to a double (while parsing a vector value)
[ERROR] [1613744905.426356186]: Could not parse inertial element for Link [head_tilt_link]
[ERROR] [1613744905.426449479]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.426485690]: Could not parse inertial element for Link [head_plate_frame]
[ERROR] [1613744905.426579829]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.426642692]: Could not parse inertial element for Link [sensor_mount_link]
[ERROR] [1613744905.426730224]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.426771594]: Could not parse inertial element for Link [high_def_frame]
[ERROR] [1613744905.426861823]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.426899307]: Could not parse inertial element for Link [high_def_optical_frame]
[ERROR] [1613744905.426978513]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.427014018]: Could not parse inertial element for Link [double_stereo_link]
[ERROR] [1613744905.427105094]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.427144812]: Could not parse inertial element for Link [wide_stereo_link]
[ERROR] [1613744905.427245829]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.427282756]: Could not parse inertial element for Link [wide_stereo_l_stereo_camera_frame]
[ERROR] [1613744905.427379709]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.427415972]: Could not parse inertial element for Link [wide_stereo_r_stereo_camera_frame]
[ERROR] [1613744905.427528414]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.427564602]: Could not parse inertial element for Link [narrow_stereo_link]
[ERROR] [1613744905.427664059]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.427699921]: Could not parse inertial element for Link [narrow_stereo_l_stereo_camera_frame]
[ERROR] [1613744905.427795854]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.427831885]: Could not parse inertial element for Link [narrow_stereo_r_stereo_camera_frame]
[ERROR] [1613744905.427928084]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.427964662]: Could not parse inertial element for Link [projector_wg6802418_frame]
[ERROR] [1613744905.428063242]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.428114795]: Could not parse inertial element for Link [projector_wg6802418_child_frame]
[ERROR] [1613744905.428184298]: Unable to parse component [-0.001136] to a double (while parsing a vector value)
[ERROR] [1613744905.428210630]: Could not parse inertial element for Link [laser_tilt_mount_link]
[ERROR] [1613744905.428279646]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.428306179]: Could not parse inertial element for Link [laser_tilt_link]
[ERROR] [1613744905.428376115]: Unable to parse component [-0.001201] to a double (while parsing a vector value)
[ERROR] [1613744905.428402552]: Could not parse inertial element for Link [r_shoulder_pan_link]
[ERROR] [1613744905.428472165]: Unable to parse component [0.02195] to a double (while parsing a vector value)
[ERROR] [1613744905.428498587]: Could not parse inertial element for Link [r_shoulder_lift_link]
[ERROR] [1613744905.428567934]: Unable to parse component [0.0] to a double (while parsing a vector value)
[ERROR] [1613744905.428595138]: Could not parse inertial element for Link [r_upper_arm_roll_link]
[ERROR] [1613744905.428654026]: Unable to parse component [0.21398] to a double (while parsing a vector value)
[ERROR] [1613744905.428680435]: Could not parse inertial element for Link [r_upper_arm_link]
[ERROR] [1613744905.428753108]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.428780626]: Could not parse inertial element for Link [r_forearm_roll_link]
[ERROR] [1613744905.428849772]: Unable to parse component [0.01014] to a double (while parsing a vector value)
[ERROR] [1613744905.428878595]: Could not parse inertial element for Link [r_elbow_flex_link]
[ERROR] [1613744905.428954919]: Unable to parse component [0.18791] to a double (while parsing a vector value)
[ERROR] [1613744905.428985475]: Could not parse inertial element for Link [r_forearm_link]
[ERROR] [1613744905.429057071]: Unable to parse component [-0.00157] to a double (while parsing a vector value)
[ERROR] [1613744905.429087929]: Could not parse inertial element for Link [r_wrist_flex_link]
[ERROR] [1613744905.429146575]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.429175503]: Could not parse inertial element for Link [r_wrist_roll_link]
[ERROR] [1613744905.429235187]: Unable to parse component [0.06623] to a double (while parsing a vector value)
[ERROR] [1613744905.429264501]: Could not parse inertial element for Link [r_gripper_palm_link]
[ERROR] [1613744905.429324362]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.429355596]: Could not parse inertial element for Link [r_gripper_motor_accelerometer_link]
[ERROR] [1613744905.429428199]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.429459845]: Could not parse inertial element for Link [r_gripper_motor_slider_link]
[ERROR] [1613744905.429533061]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.429565129]: Could not parse inertial element for Link [r_gripper_motor_screw_link]
[ERROR] [1613744905.429644151]: Unable to parse component [0.03598] to a double (while parsing a vector value)
[ERROR] [1613744905.429672665]: Could not parse inertial element for Link [r_gripper_l_finger_link]
[ERROR] [1613744905.429745145]: Unable to parse component [0.03576] to a double (while parsing a vector value)
[ERROR] [1613744905.429773194]: Could not parse inertial element for Link [r_gripper_r_finger_link]
[ERROR] [1613744905.429847374]: Unable to parse component [0.00423] to a double (while parsing a vector value)
[ERROR] [1613744905.429875234]: Could not parse inertial element for Link [r_gripper_l_finger_tip_link]
[ERROR] [1613744905.429946583]: Unable to parse component [0.00423] to a double (while parsing a vector value)
[ERROR] [1613744905.429975453]: Could not parse inertial element for Link [r_gripper_r_finger_tip_link]
[ERROR] [1613744905.430074151]: Unable to parse component [-0.001201] to a double (while parsing a vector value)
[ERROR] [1613744905.430102480]: Could not parse inertial element for Link [l_shoulder_pan_link]
[ERROR] [1613744905.430177591]: Unable to parse component [0.02195] to a double (while parsing a vector value)
[ERROR] [1613744905.430205785]: Could not parse inertial element for Link [l_shoulder_lift_link]
[ERROR] [1613744905.430277491]: Unable to parse component [0.0] to a double (while parsing a vector value)
[ERROR] [1613744905.430305160]: Could not parse inertial element for Link [l_upper_arm_roll_link]
[ERROR] [1613744905.430379558]: Unable to parse component [0.21405] to a double (while parsing a vector value)
[ERROR] [1613744905.430407262]: Could not parse inertial element for Link [l_upper_arm_link]
[ERROR] [1613744905.430478621]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.430506163]: Could not parse inertial element for Link [l_forearm_roll_link]
[ERROR] [1613744905.430579621]: Unable to parse component [0.01014] to a double (while parsing a vector value)
[ERROR] [1613744905.430618398]: Could not parse inertial element for Link [l_elbow_flex_link]
[ERROR] [1613744905.430705837]: Unable to parse component [0.18791] to a double (while parsing a vector value)
[ERROR] [1613744905.430733502]: Could not parse inertial element for Link [l_forearm_link]
[ERROR] [1613744905.430805290]: Unable to parse component [-0.00157] to a double (while parsing a vector value)
[ERROR] [1613744905.430833176]: Could not parse inertial element for Link [l_wrist_flex_link]
[ERROR] [1613744905.430907456]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.430934684]: Could not parse inertial element for Link [l_wrist_roll_link]
[ERROR] [1613744905.431006990]: Unable to parse component [0.06623] to a double (while parsing a vector value)
[ERROR] [1613744905.431034927]: Could not parse inertial element for Link [l_gripper_palm_link]
[ERROR] [1613744905.431108694]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.431136095]: Could not parse inertial element for Link [l_gripper_motor_accelerometer_link]
[ERROR] [1613744905.431210253]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.431238369]: Could not parse inertial element for Link [l_gripper_motor_slider_link]
[ERROR] [1613744905.431315438]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.431343624]: Could not parse inertial element for Link [l_gripper_motor_screw_link]
[ERROR] [1613744905.431415007]: Unable to parse component [0.03598] to a double (while parsing a vector value)
[ERROR] [1613744905.431443524]: Could not parse inertial element for Link [l_gripper_l_finger_link]
[ERROR] [1613744905.431517333]: Unable to parse component [0.03576] to a double (while parsing a vector value)
[ERROR] [1613744905.431544894]: Could not parse inertial element for Link [l_gripper_r_finger_link]
[ERROR] [1613744905.431616387]: Unable to parse component [0.00423] to a double (while parsing a vector value)
[ERROR] [1613744905.431644363]: Could not parse inertial element for Link [l_gripper_l_finger_tip_link]
[ERROR] [1613744905.431718383]: Unable to parse component [0.00423] to a double (while parsing a vector value)
[ERROR] [1613744905.431745975]: Could not parse inertial element for Link [l_gripper_r_finger_tip_link]
[ERROR] [1613744905.431823067]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.431856851]: Could not parse inertial element for Link [l_forearm_cam_frame]
[ERROR] [1613744905.431936225]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.431964181]: Could not parse inertial element for Link [r_forearm_cam_frame]
[ERROR] [1613744905.432041440]: Unable to parse component [0] to a double (while parsing a vector value)
[ERROR] [1613744905.432070149]: Malformed parent origin element for joint [base_footprint_joint]
[ERROR] [1613744905.432102347]: joint xml is not initialized correctly
[ERROR] [1613744905.432583054]: Unable to parse URDF from parameter '/robot_description'

Now, remove bio_ik from the CMakeLists.txt, recompile, and try again. The problem will not occur.

I tested this on ROS Melodic on Ubuntu 18.04 for both python2 and python3 (just replace python with python3 in the find_package(BOOST...)). The problem did not occur on a self compiled workspace on Debian Testing.

In my case it was fortunately possible to remove bio_ik from the catkin components, but that may not always be the case.

I'm sorry for the bizarre issue.

BioIK running slowly

Hi I am using bioIK together with the bio_ik_service, because the service provides a very convenient way of using bioIK. However it runs slowly, I removed some code in bio_ik_service (like doing planning and checking if request is empty or not), it still runs relative slow. In my laptop, which has Intel® Core™ i7-7700HQ CPU @ 2.80GHz × 8 , runs about 0.008s per iteration, which we think still slow because we just have a 6 DOF robot arm. Is there any ways to speed up bioIK?

Thanks!

bio_ik produces weird ik solutions

we were testing bio_ik as the kinematics plugin for moveit for a custom manipulator (total of 7 joints, including linear and mimic joints)

we observe the following:

  • generating random goal poses
  • call compute_ik service (capability)
  • on success, call compute_fk with the ik_solution
  • compare fk pose of ik_solution against random goal pose passed to ik request

❌ in some cases, fk pose of ik_solution is way off the random goal pose both wrt position (up to 0.5 m!) as well as orientation

to give numbers:
of 100 tests, we get like 65 poses where NO_IK_SOLUTION is reported (which is ok - because fully random poses might not be reachable by our manipulator), and of the 35 poses where SUCCESS is reported by compute_ik, about 7 have this weird ik solution, i.e. fk of ik solution differs significantly from the pose in the ik request

has anybody observed something similar?
is bio_ik able to handle linear joints?
is bio_ik able to handle mimich joints?

any idea how we could debug this any further?
would it make sense to add a "fk verification step" that does the fk of ik solution and compares it to the pose in the request and overwrites the outcome in case the pose diff is significant?

@v4hn @philipp1234 @rhaschke

missing redundancy resolution?

The MoveIt plugin doesn't seem to have a nice redundancy resolution mechanism.
Using BioIK on a 7-DoF arm, solutions along a Cartesian path jitter within the nullspace instead of choosing the least-squares solution.

Licenses/Usage

I was wondering about the license/usage requirements for this package.

From looking through the your public repos it appears that you tend to release with Apache 2.0 however I also found the same algorithm (or what I assume is the same) in the unity store for $20/seat (https://assetstore.unity.com/packages/tools/animation/bio-ik-67819). Does this license allow for use in ROS or is there a different license required?

We need a release

This package will not see widespread use until it is released as a package into the ROS ecosystem.

I guess the only question is whether, before we release this, we want to improve the kinematics interface in MoveIt to simplify things on this end.
Once it's released, people (like my favorite senior researcher) will complain if we break the interfaces later on.
I think as a minimum we could make KinematicsQueryOptions virtual to allow for dynamic_cast.
We could also move new constraint types into moveit_msgs to facilitate their use in parts other than IK.

Custom robot model loader does not respect joint_limits.yaml files

Many tools in MoveIt! use a RobotModelLoader create a moveit::core::RobotModel. In bio_ik a custom helper function is used. Unfortunately, this custom loader does not look at a joint_limits.yaml file (like the RobotModelLoader does). What this means is that if you have a URDF that defines one set of joint limits, and you use joint_limits.yaml file to set a different set of joint limits for the purposes of planning (a setup that is commonly used in MoveIt, including packages generated with the setup assistant). Then, when using bio_ik it's possible to get IK solutions (for example from robot_state::RobotState::setFromIK) that are outside of the motion planning limits defined by the joint_limits.yaml file, but inside of the limits defined in the URDF.

error compile this package with moveit master branch

In the geometric_shapes write:

Note: bodies::ConvexMesh::MeshData was made implementation-private in Noetic and is no longer accessible from the .h file.

That leads to the compile error in bio_ik moveit master branch
error msg is:

/bio_ik/src/goal_types.cpp:89:49: error: invalid use of incomplete type ‘using element_type = struct bodies::ConvexMesh::MeshData {aka struct bodies::ConvexMesh::MeshData}’
                         for(auto& v : mesh_data_->vertices_)

BIO_IK2

Hi everyone,
Is this repository bio_ik2? Since I see there are bio_ik1 and 2.

Thank you!

Issue when following tutorial

Hi

I am following the tutorial on read me and at the same time adapting it for use with iiwa and shadow hand.
I get an error at bio_ik::BioIKKinematicsQueryOptions ik_options;

the error is :
CMakeFiles/bioik_moveit_iiwa.dir/src/bioik_moveit_iiwa.cpp.o: In function main': bioik_moveit_iiwa.cpp:(.text+0x70c): undefined reference to bio_ik::BioIKKinematicsQueryOptions::BioIKKinematicsQueryOptions()'
bioik_moveit_iiwa.cpp:(.text+0x95f): undefined reference to bio_ik::BioIKKinematicsQueryOptions::~BioIKKinematicsQueryOptions()' bioik_moveit_iiwa.cpp:(.text+0xb89): undefined reference to bio_ik::BioIKKinematicsQueryOptions::~BioIKKinematicsQueryOptions()'
collect2: error: ld returned 1 exit status

My code is:`#include

#include <ros/ros.h>
#include <bio_ik/bio_ik.h>

#include <gazebo_ros/PhysicsConfig.h>

#include <moveit/robot_model_loader/robot_model_loader.h>
#include <moveit/kinematics_base/kinematics_base.h>
#include <moveit/robot_state/robot_state.h>

int main(int argc, char** argv)
{

ros::init (argc, argv, "bioik_moveit_iiwa");
ros::AsyncSpinner spinner(1);
spinner.start();
ros::NodeHandle node_handle;

robot_model_loader::RobotModelLoader robot_model_loader("robot_description");

auto robot_model = robot_model_loader.getModel();
//first finger ff
auto ff_joint_model_group = robot_model->getJointModelGroup("first_finger");
auto ff_tip_names = ff_joint_model_group->getSolverInstance()->getTipFrames();
std::cout <<"The links are: "<<ff_tip_names[0]<<"\n";

//middle finger mf
auto mf_joint_model_group = robot_model->getJointModelGroup("middel_finger");
auto mf_tip_names = mf_joint_model_group->getSolverInstance()->getTipFrames();
std::cout <<"The links are: "<<mf_tip_names[0]<<"\n";

//iiwa
auto iiwa_joint_model_group = robot_model->getJointModelGroup("iwaa");
auto iiwa_tip_names = iiwa_joint_model_group->getSolverInstance()->getTipFrames();
std::cout <<"The links are: "<<iiwa_tip_names[0]<<"\n";

bio_ik::BioIKKinematicsQueryOptions ik_options;
ik_options.replace = true;
ik_options.return_approximate_solution = true;

auto* ff_goal = new bio_ik::PoseGoal();
auto* mf_goal = new bio_ik::PoseGoal();
auto* iiwa_goal = new bio_ik::PoseGoal();

ff_goal->setLinkName(ff_tip_names[0]);
mf_goal->setLinkName(mf_tip_names[0]);
iiwa_goal->setLinkName(iiwa_tip_names[0]);

ik_options.goals.emplace_back(ff_goal);
ik_options.goals.emplace_back(mf_goal);
ik_options.goals.emplace_back(iiwa_goal);

robot_state::RobotState robot_state_ik(robot_model);

bool ok = robot_state_ik.setFromIK(
          ff_joint_model_group, // joints to be used for IK
          EigenSTL::vector_Affine3d(),    // multiple end-effector goal poses
          std::vector<std::string>(),         // names of the end-effector links
          3, 0.005, // solver attempts and timeout
          moveit::core::GroupStateValidityCallbackFn(),
          ik_options               // mostly empty
        );

return 0;
}
`

could you please help me with this?
thanks

Clarification on the Jacobian computation

Hello, I'm trying to understand how the Jacobian is computed in the forward_kinematic.h. The section of code that I can't understand how is derived is the following:

auto& tip_frame = tip_frames[itip];
auto q = link_frame.rot.inverse() * tip_frame.rot;
q = q.inverse();
auto rot = joint_axis_list[joint_model->getJointIndex()];
quat_mul_vec(q, rot, rot);
auto vel = link_frame.pos - tip_frame.pos;
quat_mul_vec(tip_frame.rot.inverse(), vel, vel);
vel = vel.cross(rot);

Can someone give me some hints on the method used? Is this method formalized in some paper or book?

Another specific question is: Why does the Jacobian have 6 rows? There not should be 7(3 elements for the position vector and 4 for the rotation since the quaternion is used)?

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.