Phylliade / ikpy

An Inverse Kinematics library aiming performance and modularity
http://phylliade.github.io/ikpy
Apache License 2.0
695 stars 152 forks source link

Real-time applications #92

Closed Adoplot closed 3 years ago

Adoplot commented 3 years ago

I am interested how fast is your algorithm. Can I use it to solve inverse kinematics of 6DoF Kuka robot in real-time (<16ms for every frame) ? I managed to test it using urdf file. I receive end-effector position data every 4ms from udp socket, solve IK and send joints' parameters back. I achieved IK solver speed of 200-300ms. Am I doing something wrong, or it is normal for such type of algorithm?

Thank you for your work! I appreciate it!

Phylliade commented 3 years ago

Hello @Adoplot,

This is a though question: Every IK computations involve maths optimization that are pretty heavy, thus inducing minimal computation time per Chain.inverse_kinematics call.

There are numerous ways to solve this issue, but this depends on your context:

Can you give more information about your issue, so we can find a solution that suits your need?

Adoplot commented 3 years ago

Hello @Phylliade,

Thanks for your fast reply.

As you said, I need a robot to do small jumps between close IK targets. I achieved 80-110 ms computation speed on i5-9300H processor. I tried decreasing max_iter parameter, but the result was not much different (70-100ms).

I tried to use initial_position parameter but I can't understand how to use it properly. As I understand, initial_position is a parameter of Chain.inverse_kinematics_frame, not the Chain.inverse_kinematics

For testing I have an array of 4x4 homogeneous transformation matrices (for inverse_kinematics_frame). I solve IK for 100 matrices and divide overall computation time by 100 to get average value. It works ok. But how to use initial_position parameter? I understand that I need to write there joint parameters of the robot from previous frame, but I don't know what syntax to use. Could you show an example, please?

Thank you!

alxy commented 3 years ago

You can pass initial_position to the inverse_kinematics function as well, it will be forwarded to the lower level functions.

You need to pass it the joint positions of a previous run, so just somehow cache it between two calls:

ikResults1 = armChain.inverse_kinematics(translation1)
ikResults2 = armChain.inverse_kinematics(translation2, initial_position=ikResults1)
Adoplot commented 3 years ago

@alxy, Thank you! I managed to decrease average computation time to 40-50ms. However, it is not enough.

Thanks for help!