22
33[ ![ Code style: black] ( https://img.shields.io/badge/code%20style-black-000000.svg )] ( https://github.com/psf/black )
44![ linter] ( https://github.com/pollen-robotics/reachy2_symbolic_ik/actions/workflows/lint.yml/badge.svg )
5- ![ pytest] ( https://github.com/pollen-robotics/reachy2-sdk /actions/workflows/unit_tests .yml/badge.svg )
5+ ![ pytest] ( https://github.com/pollen-robotics/reachy2_symbolic_ik /actions/workflows/pytest .yml/badge.svg )
66
77** A kinematics library for Reachy2 7 DoF robotic arms** , providing precise and reliable tools for motion control.
88
3434
3535
3636
37-
3837## Understanding how it works
3938Learn the core concepts behind our symbolic inverse kinematics approach (French with English subtitles):
4039
@@ -57,25 +56,109 @@ $ pip install -e .[dev]
5756The optional * [ dev] * option includes tools for developers.
5857
5958## Usage
60- Basic example of an inverse kinematics call. The input is a Pose of dimension 6, the output is the 7 joints of the arm:
61- ``` python
62- symbolic_ik = SymbolicIK(arm = " l_arm" )
59+ Basics examples of an inverse kinematics call. The input is a Pose of dimension 6, the output is the 7 joints of the arm:
60+
61+ <details >
62+ <summary >Example with SymbolicIK</summary >
63+
64+
65+ ``` python
66+ import numpy as np
67+ from reachy2_symbolic_ik.symbolic_ik import SymbolicIK
6368
64- # The input is a Pose = [position, orientation]
69+ # Create the symbolic IK for the right arm
70+ symbolic_ik = SymbolicIK(arm = " r_arm" )
71+
72+ # Define the goal position and orientation
6573goal_position = [0.55 , - 0.3 , - 0.15 ]
6674goal_orientation = [0 , - np.pi / 2 , 0 ]
6775goal_pose = np.array([goal_position, goal_orientation])
6876
6977# Check if the goal pose is reachable
70- is_reachable, interval, get_joints, _ = symbolic_ik_r .is_reachable(goal_pose)
78+ is_reachable, theta_interval, theta_to_joints_func, state = symbolic_ik .is_reachable(goal_pose)
7179
80+ # Get the joints for one elbow position, defined by the angle theta
81+ if is_reachable:
82+ # Choose a theta in the interval
83+ # if theta_interval[0] < theta_interval[1], theta can be any value in the interval
84+ # else theta can be in the intervals [-np.pi, theta_interval[1]] or [theta_interval[0], np.pi]
85+ theta = theta_interval[0 ]
86+
87+ # Get the joints
88+ joints, elbow_position = theta_to_joints_func(theta)
89+ print (f " Pose is reachable \n Joints: { joints} " )
90+ else :
91+ print (" Pose not reachable" )
92+ ```
93+ </details >
94+
95+ <details >
96+ <summary >Example with ControlIK</summary >
97+
98+ ``` python
99+ import numpy as np
100+ from reachy2_symbolic_ik.control_ik import ControlIK
101+ from reachy2_symbolic_ik.utils import make_homogenous_matrix_from_rotation_matrix
102+ from scipy.spatial.transform import Rotation as R
103+
104+ # Create the control IK for the right arm
105+ control = ControlIK(urdf_path = " ../config_files/reachy2.urdf" )
106+
107+ # Define the goal position and orientation
108+ goal_position = [0.55 , - 0.3 , - 0.15 ]
109+ goal_orientation = [0 , - np.pi / 2 , 0 ]
110+ goal_pose = np.array([goal_position, goal_orientation])
111+ goal_pose = make_homogenous_matrix_from_rotation_matrix(goal_position, R.from_euler(" xyz" , goal_orientation).as_matrix())
112+
113+ # Get joints for the goal pose
114+ # The control type can be "discrete" or "continuous"
115+ # If the control type is "discrete", the control will choose the best elbow position for the goal pose
116+ # If the control type is "continuous", the control will choose a elbow position that insure continuity in the joints
117+ control_type = " discrete"
118+ joints, is_reachable, state = control.symbolic_inverse_kinematics(" r_arm" , goal_pose, control_type)
72119if is_reachable:
73- # Choose the elbow position inside the valid interval
74- theta = interval[0 ]
75- joints, elbow_position = get_joints(theta)
120+ print (f " Pose is reachable \n Joints: { joints} " )
76121else :
77122 print (" Pose not reachable" )
78123```
124+ </details >
125+
126+ <details >
127+ <summary >Example with SDK</summary >
128+
129+ For this example, you will need [ Reachy2 SDK] ( https://github.com/pollen-robotics/reachy2-sdk )
130+ ``` python
131+ import time
132+ import numpy as np
133+ from reachy2_sdk import ReachySDK
134+ from scipy.spatial.transform import Rotation as R
135+ from reachy2_symbolic_ik.utils import make_homogenous_matrix_from_rotation_matrix
136+
137+ # Create the ReachySDK object
138+ print (" Trying to connect on localhost Reachy..." )
139+ reachy = ReachySDK(host = " localhost" )
140+
141+ time.sleep(1.0 )
142+ if reachy._grpc_status == " disconnected" :
143+ print (" Failed to connect to Reachy, exiting..." )
144+ return
145+
146+ reachy.turn_on()
147+
148+ # Define the goal pose
149+ goal_position = [0.55 , - 0.3 , - 0.15 ]
150+ goal_orientation = [0 , - np.pi / 2 , 0 ]
151+ goal_pose = np.array([goal_position, goal_orientation])
152+ goal_pose = make_homogenous_matrix_from_rotation_matrix(goal_position, R.from_euler(" xyz" , goal_orientation).as_matrix())
153+
154+ # Get joints for the goal pose
155+ joints = reachy.r_arm.inverse_kinematics(goal_pose)
156+
157+ # Go to the goal pose
158+ reachy.r_arm.goto(joints, duration = 4.0 , degrees = True , interpolation_mode = " minimum_jerk" , wait = True )
159+ ```
160+ </details >
161+
79162Check the ` /src/example ` folder for complete examples.
80163
81164## Unit tests
@@ -86,18 +169,21 @@ To ensure everything is functioning correctly, run the unit tests.
86169$ pytest
87170```
88171
89- Some unit tests need [ Placo ] ( https://github.com/pollen-robotics/reachy_placo ) and some need reachy2_sdk .
172+ Some unit tests need [ Reachy2 SDK ] ( https://github.com/pollen-robotics/reachy2-sdk ) .
90173
91174You can decide which test you want to run with a flag.
92175- sdk : run tests with sdk
93- - placo : run tests with placo
94176- cicd : run tests using only reachy2_symbolic_ik
95177
96178Example :
97179
98180``` console
99181$ pytest -m cicd
100182```
183+ or
184+ ``` console
185+ $ python3 -m pytest -m cicd
186+ ```
101187
102188## URDF
103189
0 commit comments