Skip to content

Commit 4670626

Browse files
committed
Update basics examples
1 parent dc3147e commit 4670626

File tree

7 files changed

+199
-223
lines changed

7 files changed

+199
-223
lines changed

README.md

Lines changed: 98 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
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

@@ -34,7 +34,6 @@
3434

3535

3636

37-
3837
## Understanding how it works
3938
Learn the core concepts behind our symbolic inverse kinematics approach (French with English subtitles):
4039

@@ -57,25 +56,109 @@ $ pip install -e .[dev]
5756
The 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
6573
goal_position = [0.55, -0.3, -0.15]
6674
goal_orientation = [0, -np.pi / 2, 0]
6775
goal_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 \nJoints: {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)
72119
if 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 \nJoints: {joints}")
76121
else:
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+
79162
Check 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

91174
You 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

96178
Example :
97179

98180
```console
99181
$ pytest -m cicd
100182
```
183+
or
184+
```console
185+
$ python3 -m pytest -m cicd
186+
```
101187

102188
## URDF
103189

src/example/control_ik_basics.py

Lines changed: 0 additions & 98 deletions
This file was deleted.

src/example/example_control.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import time
2+
3+
import numpy as np
4+
5+
from reachy2_symbolic_ik.control_ik import ControlIK
6+
from reachy2_symbolic_ik.utils import make_homogenous_matrix_from_rotation_matrix
7+
from scipy.spatial.transform import Rotation as R
8+
9+
10+
def control_basics() -> None:
11+
# Create the control IK for the right arm
12+
control = ControlIK(urdf_path="../config_files/reachy2.urdf")
13+
14+
# Define the goal position and orientation
15+
goal_position = [0.55, -0.3, -0.15]
16+
goal_orientation = [0, -np.pi / 2, 0]
17+
goal_pose = np.array([goal_position, goal_orientation])
18+
goal_pose = make_homogenous_matrix_from_rotation_matrix(goal_position, R.from_euler("xyz", goal_orientation).as_matrix())
19+
20+
# Get joints for the goal pose
21+
# The control type can be "discrete" or "continuous"
22+
# If the control type is "discrete", the control will choose the best elbow position for the goal pose
23+
# If the control type is "continuous", the control will choose a elbow position that insure continuity in the joints
24+
control_type = "discrete"
25+
joints, is_reachable, state = control.symbolic_inverse_kinematics("r_arm", goal_pose, control_type)
26+
if is_reachable:
27+
print(f"Joints: {joints}")
28+
else:
29+
print("Pose not reachable")
30+
31+
32+
if __name__ == "__main__":
33+
control_basics()

src/example/example_ik.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import numpy as np
2+
3+
from reachy2_symbolic_ik.symbolic_ik import SymbolicIK
4+
5+
def ik_basics() -> None:
6+
#Create the symbolic IK for the right arm
7+
symbolic_ik = SymbolicIK(arm="r_arm")
8+
9+
# Define the goal position and orientation
10+
goal_position = [0.55, -0.3, -0.15]
11+
goal_orientation = [0, -np.pi / 2, 0]
12+
goal_pose = np.array([goal_position, goal_orientation])
13+
14+
# Check if the goal pose is reachable
15+
is_reachable, theta_interval, theta_to_joints_func, state = symbolic_ik.is_reachable(goal_pose)
16+
17+
# Get the joints for one elbow position, defined by the angle theta
18+
if is_reachable:
19+
# Choose a theta in the interval
20+
# if theta_interval[0] < theta_interval[1], theta can be any value in the interval
21+
# else theta can be in the intervals [-np.pi, theta_interval[1]] or [theta_interval[0], np.pi]
22+
theta = theta_interval[0]
23+
24+
# Get the joints
25+
joints, elbow_position = theta_to_joints_func(theta)
26+
print(f"Pose is reachable \nJoints: {joints}")
27+
else:
28+
print("Pose not reachable")
29+
30+
31+
if __name__ == "__main__":
32+
ik_basics()

src/example/example_sdk.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import time
2+
3+
import numpy as np
4+
from reachy2_sdk import ReachySDK
5+
from scipy.spatial.transform import Rotation as R
6+
from reachy2_symbolic_ik.utils import make_homogenous_matrix_from_rotation_matrix
7+
8+
def sdk_basics() -> None:
9+
# Create the ReachySDK object
10+
print("Trying to connect on localhost Reachy...")
11+
reachy = ReachySDK(host="localhost")
12+
13+
time.sleep(1.0)
14+
if reachy._grpc_status == "disconnected":
15+
print("Failed to connect to Reachy, exiting...")
16+
return
17+
18+
reachy.turn_on()
19+
20+
# Define the goal pose
21+
goal_position = [0.55, -0.3, -0.15]
22+
goal_orientation = [0, -np.pi / 2, 0]
23+
goal_pose = np.array([goal_position, goal_orientation])
24+
goal_pose = make_homogenous_matrix_from_rotation_matrix(goal_position, R.from_euler("xyz", goal_orientation).as_matrix())
25+
26+
# Get joints for the goal pose
27+
joints = reachy.r_arm.inverse_kinematics(goal_pose)
28+
29+
# Go to the goal pose
30+
reachy.r_arm.goto(joints, duration=4.0, degrees=True, interpolation_mode="minimum_jerk", wait=True)
31+
32+
33+
if __name__ == "__main__":
34+
sdk_basics()
35+
36+

src/example/graph_singularity.py

Lines changed: 0 additions & 25 deletions
This file was deleted.

0 commit comments

Comments
 (0)