Repository: pollen-robotics/reachy-sdk (language: python)

Issue:
Camera and Zoom APIs



Discussion / hints:

Fix patch:
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
new file mode 100644
index 0000000..dc5f191
--- /dev/null
+++ b/.github/workflows/lint.yml
@@ -0,0 +1,16 @@
+name: Lint using flake8.
+on: [push]
+
+jobs:
+  lint:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v2
+    - uses: actions/setup-python@v2
+      with:
+        python-version: '3.8'
+
+    - name: Lint with flake8
+      run: |
+        pip install flake8 flake8-docstrings
+        python -m flake8 . --count --show-source --statistics
\ No newline at end of file
diff --git a/.github/workflows/publish_pypi.yml b/.github/workflows/publish_pypi.yml
new file mode 100644
index 0000000..86b043c
--- /dev/null
+++ b/.github/workflows/publish_pypi.yml
@@ -0,0 +1,25 @@
+name: Upload Python Package on Pypi.
+
+on:
+  release:
+    types: [created]
+
+jobs:
+  deploy:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v2
+    - uses: actions/setup-python@v2
+      with:
+        python-version: '3.x'
+    - name: Install dependencies
+      run: |
+        python -m pip install --upgrade pip
+        pip install setuptools wheel twine
+    - name: Build and publish
+      env:
+        TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
+        TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
+      run: |
+        python setup.py sdist bdist_wheel
+        twine upload dist/*
\ No newline at end of file
diff --git a/README.md b/README.md
index 40b30ee..a14ccc7 100644
--- a/README.md
+++ b/README.md
@@ -1,1 +1,92 @@
-# reachy_sdk
\ No newline at end of file
+# Reachy 2021 Python SDK
+
+Reachy Python SDK is a pure python SDK library that let you control and interact with a [Reachy robot](https://www.pollen-robotics.com/reachy/). Reachy and its SDK are developed by [Pollen Robotics](https://www.pollen-robotics.com). 
+
+This SDK is intended to work with the Reachy 2021 version.
+
+<img src="https://www.pollen-robotics.com/img/reachy/homepage_feature.png" width="400" alt="Reachy 2021 says hello!">
+
+
+It lets you get the current state of the robot (all joints position, the sensors up-to-date value, camera image) without having to think about synchronisation with the hardware.
+You can also send commands to control Reachy both in joint and cartesian spaces. You can control other effectors as well such as its fan or the camera zoom.
+
+The SDK also provides higher level function to easily create complex motions such as asynchronous goto command.
+
+You can use the SDK over the network, either WiFi or Ethernet but you should favour the second option for low-latency control. The communication to the robot is done via [gRPC](https://grpc.io) and can thus work on most kind of network configurations. Local control of the robot (directly on Reachy's computer can simply be done using the localhost IP)
+
+## License
+
+The SDK, and the rest of Reachy software, is open-source and released under an Apache-2.0 License.
+
+## Installation
+
+The SDK can be installed on any computer running Python 3.6 or later. 
+
+You can install the SDK:
+
+#### From PyPi
+```bash
+pip install reachy-sdk
+```
+
+#### From the source
+
+```bash
+git clone https://github.com/pollen-robotics/reachy-sdk
+pip install -e reachy-sdk
+```
+
+We recommend using [virtual environment](https://docs.python.org/3/tutorial/venv.html) for your development.
+
+The SDK depends on [numpy](https://numpy.org), [opencv](https://opencv.org) and [grpc](https://grpc.io). Most of the documentation is available as [jupyter notebooks](https://jupyter.org).
+
+## Getting Started
+
+To get started with your Reachy installation and setup, see our [official guide](TODO).
+
+To get started with the SDK, you should have a look at all our [notebooks](./notebooks).
+
+Connecting the SDK to a real robot is as simple as:
+
+```python
+from reachy_sdk import ReachySDK
+
+reachy = ReachySDK(host='my-reachy-ip')
+```
+
+Gettting the current joints position can be done via:
+
+```python
+for joint in reachy.joints:
+    print(f'Joint {joint.name} is at position {joint.present_position} degree.')
+```
+
+And displaying, via matplotlib, the last image of the left camera:
+
+```python
+import cv2 as cv
+from matplotlib import pyplot as plt
+
+plt.figure()
+plt.plot(cv.cvtColor(reachy.left_camera.last_frame, cv.COLOR_BGR2RGB))
+```
+
+For more advanced examples, see the different [notebooks](./notebooks). Also note that the SDK will automatically reflect your Reachy configuration you have (Arm, Starter Kit or Full Kit). Thus, all joints or sensors you see in the examples won't necessarly be available on your specific SDK.
+
+## APIs
+
+The SDK APIs can be accessed here: [TODO](TODO) (generated by [Sphinx](https://www.sphinx-doc.org/en/master/)).
+
+## Support 
+
+This project adheres to the Contributor [code of conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to [contact@pollen-robotics.com](mailto:contact@pollen-robotics.com).
+
+Visit [pollen-robotics.com](https://pollen-robotics.com) to learn more or visit [our forum](https://forum.pollen-robotics.com) if you have any questions.
+Follow [@PollenRobotics](https://twitter.com/pollenrobotics) on Twitter for important announcements.
+
+## Contributing
+
+
+Do not hesitate to share your experience with Pyluos and meet other Luos users on our forum!
+
+
diff --git a/notebooks/Joint control.ipynb b/notebooks/Joint control.ipynb
new file mode 100644
index 0000000..0bf9c42
--- /dev/null
+++ b/notebooks/Joint control.ipynb
@@ -0,0 +1,544 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Reachy's joints"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "In this notebook you will learn how to use Reachy's SDK to control Reachy's motors!"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "First, you need to connect to your Reachy. You will use *ReachySDK* for that.\n",
+    "The *ReachySDK* object takes three arguments at init, one of them is *host* (you don't need to worry about the others).\n",
+    "\n",
+    "If you're working directly on Reachy, use \n",
+    "```python\n",
+    "host='localhost'\n",
+    "```\n",
+    "If not, just get Reachy's IP address with\n",
+    "```bash\n",
+    "$ ifconfig\n",
+    "```\n",
+    "and put this addreess in the *host* argument."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from reachy_sdk import ReachySDK"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "reachy = ReachySDK(host='localhost')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "You can use ReachySDK from any computer, as long as it and Reachy are connected to the same network."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "There are 21 motors in Reachy's advanced version: 8 per arm, 3 for the orbita actuator used as the neck and 1 per antenna.\n",
+    "\n",
+    "With the *reachy* you just instanciated, you can easily access each joints."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['l_shoulder_pitch',\n",
+       " 'l_shoulder_roll',\n",
+       " 'l_arm_yaw',\n",
+       " 'l_elbow_pitch',\n",
+       " 'l_forearm_yaw',\n",
+       " 'l_wrist_pitch',\n",
+       " 'l_wrist_roll',\n",
+       " 'l_gripper',\n",
+       " 'r_shoulder_pitch',\n",
+       " 'r_shoulder_roll',\n",
+       " 'r_arm_yaw',\n",
+       " 'r_elbow_pitch',\n",
+       " 'r_forearm_yaw',\n",
+       " 'r_wrist_pitch',\n",
+       " 'r_wrist_roll',\n",
+       " 'r_gripper',\n",
+       " 'l_antenna',\n",
+       " 'r_antenna',\n",
+       " 'neck_disk_top',\n",
+       " 'neck_disk_middle',\n",
+       " 'neck_disk_bottom']"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "joints_names = [joint.name for joint in reachy.joints]\n",
+    "joints_names"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "You can identify each arm joint with the documentation: \n",
+    "\n",
+    "<img src=\"https://raw.githubusercontent.com/pollen-robotics/reachy-sdk/notebooks_documentation/notebooks/images/joint_control/arm_schematic.png?token=AHZJ5IAJQY3H2PONEKMC2ALAMGXOU\" alt=\"drawing\" width=\"400\"/>\n",
+    "\n",
+    "Same with Obita:\n",
+    "\n",
+    "<img src=\"https://raw.githubusercontent.com/pollen-robotics/reachy-sdk/notebooks_documentation/notebooks/images/joint_control/orbita.png?token=AHZJ5IDJBAWK6TED4M7TLQDAMGX52\" alt=\"drawing\" width=\"700\"/>"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "For each joint, you can have acces to multiple information such as the position or the temperature, using the *registers()* method. "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'name': 'r_shoulder_pitch',\n",
+       " 'uid': 8,\n",
+       " 'present_position': 5.474197690505643,\n",
+       " 'temperature': 37.0,\n",
+       " 'compliant': True,\n",
+       " 'goal_position': 1.6060657291973135,\n",
+       " 'speed_limit': 0.0,\n",
+       " 'torque_limit': 100.0,\n",
+       " 'pid': (32.0, 0.0, 0.0)}"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "reachy.r_shoulder_pitch.registers()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Name/uid"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Each joint has a name and a unique id associated so that when you want to get joints information, use the kinematics or use the *goto* function, you can either use the name or the id."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "l_shoulder_pitch got id 0\n",
+      "l_shoulder_roll got id 1\n",
+      "l_arm_yaw got id 2\n",
+      "l_elbow_pitch got id 3\n",
+      "l_forearm_yaw got id 4\n",
+      "l_wrist_pitch got id 5\n",
+      "l_wrist_roll got id 6\n",
+      "l_gripper got id 7\n",
+      "r_shoulder_pitch got id 8\n",
+      "r_shoulder_roll got id 9\n",
+      "r_arm_yaw got id 10\n",
+      "r_elbow_pitch got id 11\n",
+      "r_forearm_yaw got id 12\n",
+      "r_wrist_pitch got id 13\n",
+      "r_wrist_roll got id 14\n",
+      "r_gripper got id 15\n",
+      "l_antenna got id 16\n",
+      "r_antenna got id 17\n",
+      "neck_disk_top got id 18\n",
+      "neck_disk_middle got id 19\n",
+      "neck_disk_bottom got id 20\n"
+     ]
+    }
+   ],
+   "source": [
+    "for joint in reachy.joints:\n",
+    "    print(f'{joint.name} got id {joint.uid}')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Present position"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "You can get the present position of each Reachy's joint.\n",
+    "\n",
+    "This can be useful when you want to record a movement. For example you want to lift an object, you move the arm once yourself, store the *present_position* of each joint involved and replay it. This what we used to get the movements in our [Tictactoe application](https://www.youtube.com/watch?v=aGheS4HXEvI)!\n",
+    "\n",
+    "Also if you want to teach movements to the robot with learning technics, storing the *present_position* of the joints will help you build a dataset.  "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Present position of r_shoulder_pitch joint is 5.5 degrees.\n"
+     ]
+    }
+   ],
+   "source": [
+    "# for joint in reachy.joints:\n",
+    "print(f'Present position of r_shoulder_pitch joint is {\"%.1f\" %(reachy.r_shoulder_pitch.present_position)} degrees.')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Temperature"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "You also have access to each motors temperatures with the *temperature* attribute of each joint. \n",
+    "This temperature should be checked to make sure that the robot can operate correctly. The temperature is also monitored internally in Reachy and fans are turned on when the joints are heating.  \n",
+    "\n",
+    "\n",
+    "See [Safety.ipynb notebook](https://github.com/pollen-robotics/reachy-sdk/blob/notebooks_documentation/notebooks/Safety.ipynb) for more information."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Temperature of r_shoulder_pitch joint is 37.0 Celsius degrees.\n"
+     ]
+    }
+   ],
+   "source": [
+    "# for joint in reachy.joints:\n",
+    "print(f'Temperature of r_shoulder_pitch joint is {reachy.r_shoulder_pitch.temperature} Celsius degrees.')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Compliant"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Each Reachy's joint can be in two modes: **compliant** and **stiff**.\n",
+    "\n",
+    "In the compliant mode, you can move the joint freely with your hands. \n",
+    "\n",
+    "In stiff mode, the joint will use its torque to stay in its present position. You can not move a motor in stiff mode with your hands. The only way to move the joint is by setting its *goal_position*. \n",
+    "\n",
+    "**Important:** Keep that in mind, if a joint does not move when you're changing its *goal_position*, it's very likely that it is in compliant mode."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Right now, Reachy's joints are in compliant mode, you can move each joint with your hands, try it!\n",
+    "\n",
+    "Now let's turn Reachy's joints in stiff mode so that you can feel the difference. You should hear a small noise when the joints are in stiff mode, the noise should increase if you try to move with your hands a joint in stiff mode."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "for joint in reachy.joints:\n",
+    "    joint.compliant = False"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Try to move with the arms or the head, you should feel the joints resisting. \n",
+    "\n",
+    "Now, let's put the joints back to compliant mode."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "for joint in reachy.joints:\n",
+    "    joint.compliant = True"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Goal position"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "As mentionned before, the *goal_position* attribute of a joint is what you need to set to move a joint.\n",
+    "\n",
+    "For example, let's put the right arm in the right-angled position. \n",
+    "\n",
+    "**Important:** Make sure that the arm is placed on a table before and that there are no obstacles preventing Reachy from executing this movement. "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# First, put the arm's joints in stiff mode\n",
+    "for joint in reachy.joints[8:16]:\n",
+    "    joint.compliant = False\n",
+    "\n",
+    "# Define what the goal_position of each joint will be\n",
+    "right_angle_position = {\n",
+    "    'r_shoulder_roll': 0,\n",
+    "    'r_arm_yaw': 0,\n",
+    "    'r_elbow_pitch': -90,\n",
+    "    'r_forearm_yaw': 0,\n",
+    "    'r_wrist_pitch': 0,\n",
+    "    'r_wrist_roll': 0,\n",
+    "    'r_gripper': 0,\n",
+    "}\n",
+    "\n",
+    "#Set each goal_position\n",
+    "from operator import attrgetter\n",
+    "\n",
+    "for name, goal in zip(right_angle_position.keys(), right_angle_position.values()):\n",
+    "    joint = attrgetter(name)(reachy)\n",
+    "    joint.goal_position = goal"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Normally Reachy's right arm should be in the right-angled position!\n",
+    "\n",
+    "Now we will put the arm back on the table by putting the joints in compliant mode. Place your hand below the arm to prevent it from falling hard on the table. "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "for joint in reachy.joints[8:16]:\n",
+    "    joint.compliant = True"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Torque/Speed limit"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The torque limit represents the percentage of maximum torque that the motor will use to stay in its present position when it is in stiff mode.\n",
+    "We set it to 100% on each joint."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "100.0"
+      ]
+     },
+     "execution_count": 17,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "reachy.r_shoulder_pitch.torque_limit"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "According to the motors documentation, the speed is in rpm (raw per minute).\n",
+    "\n",
+    "<img src=\"https://raw.githubusercontent.com/pollen-robotics/reachy-sdk/notebooks_documentation/notebooks/images/joint_control/dynamixel_speed.png\" alt=\"drawing\" width=\"600\"/>\n",
+    "\n",
+    "source: https://emanual.robotis.com/docs/en/dxl/ax/ax-18a/#ccw-angle-limit\n",
+    "\n",
+    "We set the speed limit to 0 on each joint, meaning that the motors work at maximum speed. "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0.0"
+      ]
+     },
+     "execution_count": 18,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "reachy.r_shoulder_pitch.speed_limit"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "**Important:** We recommand you NOT to change these values. When you want to make movements with Reachy, it's better to replay recorded trajectories or to work with the *goto* function from the API. *goto* computes a trajectory betweeen two points, see [Kinematics.ipynb](https://github.com/pollen-robotics/reachy-sdk/blob/notebooks_documentation/notebooks/Kinematics.ipynb) for more details.  "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### PID"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "You can check and set the pid of each joint with the *pid* attribute."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(32.0, 0.0, 0.0)"
+      ]
+     },
+     "execution_count": 19,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "reachy.r_shoulder_pitch.pid"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "If you are familiar with control theory, you'll know what it represents, if not don't worry just ignore it! "
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.8.5"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/notebooks/Kinematics.ipynb b/notebooks/Kinematics.ipynb
new file mode 100644
index 0000000..793b30f
--- /dev/null
+++ b/notebooks/Kinematics.ipynb
@@ -0,0 +1,763 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Reachy kinematics"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "In this notebook we will talk about kinematics!"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "As explained in other notebooks, usign ReachySDK you can change the joints positions if and only if the motors are in stiff mode. There are two ways to send a new target position: \n",
+    "\n",
+    "* **with goal_position**: when this attribute is set, the joint will try to reach the position it as fast as it can and it can be pretty fast (up to 700 degrees per second). You can lower the *speed_limit* but we don't recommend to use this method as it gets really hard to follow complex trajectories and have precise timing. Even though you can change the motor speed, you have no control over the acceleration.  \n",
+    "\n",
+    "\n",
+    "* **using goto()**: instead of playing with the goal_position you can use the *goto* method that is implemented in the SDK. This method generates a trajectory between the present position and the goal position. This trajectory is then interpolated at a predefined frequency (100Hz) to compute all intermediary target positions that should be followed before reaching the final goal position. Depending on the interpolation mode chosen, you can have a better control over speed and acceleration.\n",
+    "\n",
+    "The two interpolation modes that we use consist in working either linearly or with the minjerk function.\n",
+    "\n",
+    "<img src=\"https://raw.githubusercontent.com/pollen-robotics/reachy-sdk/notebooks_documentation/notebooks/images/kinematics/interpolation.png?token=AHZJ5IBL7QZHESYVASSGUEDAMG7FU\" alt=\"drawing\" width=\"500\"/>"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Both trajectories start and finish at the same point but don't follow the same intermediate positions.\n",
+    "The minimum jerk will slowly accelerate at the begining and slowly decelerate at the end. This makes the movements more natural, you'll see this below."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Now let's make our robot move! We will make the same arm movement but in three different ways, by setting the *goal_position* and using the *goto* method with each interpolation mode."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "We will put Reachy's right arm in the right-angled position. First, place it on a table and make sure that there will be no obstacles along its way."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from reachy_sdk import ReachySDK\n",
+    "\n",
+    "from reachy_sdk.trajectory.interpolation import InterpolationMode"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "reachy = ReachySDK(host='localhost')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "r_shoulder_pitch\n",
+      "r_shoulder_roll\n",
+      "r_arm_yaw\n",
+      "r_elbow_pitch\n",
+      "r_forearm_yaw\n",
+      "r_wrist_pitch\n",
+      "r_wrist_roll\n",
+      "r_gripper\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Reachy's right arm joints are joints 8 to 15\n",
+    "for joint in reachy.joints[8:16]:\n",
+    "    print(joint.name)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### goal_position"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "First, we will use set the *goal_position* on each joint to put the right arm in a right-angled position. "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Put the joints in stiff mode\n",
+    "for joint in reachy.joints[8:16]:\n",
+    "    joint.compliant = False"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Define what the goal_position of each joint will be\n",
+    "right_angle_position = {\n",
+    "    'r_shoulder_pitch': 0,\n",
+    "    'r_shoulder_roll': 0,\n",
+    "    'r_arm_yaw': 0,\n",
+    "    'r_elbow_pitch': -90,\n",
+    "    'r_forearm_yaw': 0,\n",
+    "    'r_wrist_pitch': 0,\n",
+    "    'r_wrist_roll': 0,\n",
+    "    'r_gripper': 0,\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#Set each goal_position\n",
+    "from operator import attrgetter\n",
+    "\n",
+    "for name, goal in zip(right_angle_position.keys(), right_angle_position.values()):\n",
+    "    joint = attrgetter(name)(reachy)\n",
+    "    joint.goal_position = goal"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "A bit too fast, isn't it? The problem with this is that you can't control the movement's speed."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Now we will put the joints back to compliant mode, so put your hand below the arm to prevent the arm from falling on the table."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "for joint in reachy.joints[8:16]:\n",
+    "    joint.compliant = True"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Next, let's play the same movement but using the *goto* method."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### goto with linear interpolation"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# First put the joints of the right arm in stiff mode\n",
+    "for joint in reachy.joints[8:16]:\n",
+    "    joint.compliant = False"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "reachy.goto(\n",
+    "    {getattr(reachy, joint.name): gp for joint, gp in zip(reachy.joints[8:16], right_angle_position.values())},\n",
+    "duration=1.0,\n",
+    "interpolation_mode=InterpolationMode.LINEAR,\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "You can play with the duration parameter, the unit is in seconds."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# First put the joints of the right arm in stiff mode\n",
+    "for joint in reachy.joints[8:16]:\n",
+    "    joint.compliant = True"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### goto with minjerk interpolation"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 59,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# First put the joints of the right arm in stiff mode\n",
+    "for joint in reachy.joints[8:16]:\n",
+    "    joint.compliant = False"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 60,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "reachy.goto(\n",
+    "    {getattr(reachy, joint.name): gp for joint, gp in zip(reachy.joints[8:16], harder_pos.values())},\n",
+    "duration=1.0,\n",
+    "interpolation_mode=InterpolationMode.MINIMUM_JERK\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "for joint in reachy.joints[8:16]:\n",
+    "    joint.compliant = True"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The use of goto has the advantage of easily giving control on the trajectory time. The difference between the two interpolation modes might not be huge on a simple movement like the on we just did, but on more complexe ones, the difference can be quite important. \n",
+    "\n",
+    "Like we said before, minjerk interpolation gives more natural movements. Try it yourself with custom movements!\n",
+    "\n",
+    "You can try with the following goal position for example where Reachy places its right end-effector on its right hip."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "hand_on_hip_pos = {\n",
+    "'r_shoulder_pitch': 16.726945447159054,\n",
+    " 'r_shoulder_roll': -66.43789209449601,\n",
+    " 'r_arm_yaw': 61.054944877528094,\n",
+    " 'r_elbow_pitch': -120.92307608487477,\n",
+    " 'r_forearm_yaw': -12.463343291751162,\n",
+    " 'r_wrist_pitch': -27.824175772826795,\n",
+    " 'r_wrist_roll': 41.20234435672571,\n",
+    " 'r_gripper': -25.073313669509574\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Arm coordinate system"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Joint coordinates"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "In all examples above, we have used what is called joint coordinates to move Reachy. This means that we have controlled each joint separately."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Kinematic model"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Controlling a robot in joint coordinates can be hard and is often far from what we actually do as humans. When we want to grasp an object in front of us, we think of where we should put our hand, not how to flex each individual muscle to reach this position. This approach relies on the cartesian coordinates: the 3D position and orientation in space.\n",
+    "\n",
+    "Forward and Inverse Kinematics is a way to go from one coordinates system to the other:\n",
+    "\n",
+    "* **forward kinematics: joint coordinates –> cartesian coordinates**\n",
+    "* **inverse kinematics: cartesian coordinates –> joint coordinates**\n",
+    "\n",
+    "We have defined the whole kinematic model of the arm. This means the translation and rotation required to go from one joint to the next one. On a right arm equipped with a force gripper this actually look like this:\n",
+    "\n",
+    "<img src=\"https://raw.githubusercontent.com/pollen-robotics/reachy-sdk/notebooks_documentation/notebooks/images/kinematics/right_arm_kinematic_model.png?token=AHZJ5IGJ7XNJFFZHHQTTZODAMHYQG\" alt=\"drawing\" width=\"300\"/>"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "To use and understand the kinematic model, you need to know how Reachy coordinate system is defined (from Reachy's perspective), see below:\n",
+    "\n",
+    "<img src=\"https://raw.githubusercontent.com/pollen-robotics/reachy-sdk/notebooks_documentation/notebooks/images/kinematics/arm_axis.png?token=AHZJ5ID66GQKUY3FBQ74GR3AMHNIU\" alt=\"drawing\" width=\"300\"/>\n",
+    "\n",
+    "* the X axis corresponds to the foward arrow.\n",
+    "* the Y axis corresponds to the right to left arrow.\n",
+    "* the Z axis corresponds to the up arrow.\n",
+    "\n",
+    "The origin of this coordinate system is located in the upper part of the robot trunk. Basically, if you imagine a segment going from the left shoulder to the right shoulder of the robot, the origin is the middle of this segment.\n",
+    "\n",
+    "The units used for this coordinate system are the meter. So the point (0.3, -0.2, 0) is 30cm in front of the origin, 20cm to the right and at the same height."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Forward kinematics"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Using the joint coordinates and the kinematic model defined above, we can compute the 3D position and orientation of the right or left end-effector with the *forward_kinematics* method.\n",
+    "\n",
+    "We consider the end-effector to be in a virtual joint located in the gripper and referred as *'right_tip'* or *'left_tip'* in the [urdf file](https://github.com/pollen-robotics/reachy_kinematics/blob/master/reachy.URDF), as shown below. "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "<img src=\"https://raw.githubusercontent.com/pollen-robotics/reachy-sdk/notebooks_documentation/notebooks/images/kinematics/eef.png\" alt=\"drawing\" width=\"200\"/>\n",
+    "\n",
+    "The red dot corresponds to the *'right_tip'*.\n",
+    "\n",
+    "You can see the right and left end-effectors animated in the gif below.\n",
+    "\n",
+    "<img src=\"https://raw.githubusercontent.com/pollen-robotics/reachy-sdk/notebooks_documentation/notebooks/images/safety/reachy_eef.gif\" alt=\"drawing\" width=\"300\"/>"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "As explained, the forward kinematics allows to go from the joint coordinates system to the cartesian coordinates system. Both arms have their *forward_kinematics* method."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "array([[ 0.06368817, -0.02263947, -0.99771302,  0.32420031],\n",
+       "       [ 0.07383961,  0.99710925, -0.01791228, -0.19942696],\n",
+       "       [ 0.99523441, -0.07252994,  0.06517575, -0.42596169],\n",
+       "       [ 0.        ,  0.        ,  0.        ,  1.        ]])"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "reachy.r_arm.forward_kinematics()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The 4x4 matrix returned by the *forward_kinematics* method is what is often called a pose. It actually encodes both the 3D translation (as a 3D vector) and the 3D rotation (as a 3x3 matrix) into one single representation. \n",
+    "\n",
+    "\\begin{bmatrix}\n",
+    "R_{11} & R_{12} & R_{13} & T_{x} \\\\\n",
+    "R_{21} & R_{22} & R_{23} & T_{y} \\\\\n",
+    "R_{31} & R_{32} & R_{33} & T_{z} \\\\\n",
+    "0 & 0 & 0 & 1 \\\\\n",
+    "\\end{bmatrix}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The instruction \n",
+    "\n",
+    "```python\n",
+    "reachy.r_arm.forward_kinematics()\n",
+    "```\n",
+    "\n",
+    "returns the current pose of the right end-effector, based on the present position of every joint in the right arm. \n",
+    "\n",
+    "You can also compute the pose for a given joints position, to do that just pass the list of position as argument of *forward_kinematics*. Be careful to respect the order of the position you give.\n",
+    "\n",
+    "For example, we can compute the forward kinematics for the right-angle position we used earlier."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "array([[ 0.    ,  0.    , -1.    ,  0.3675],\n",
+       "       [ 0.    ,  1.    ,  0.    , -0.202 ],\n",
+       "       [ 1.    ,  0.    ,  0.    , -0.28  ],\n",
+       "       [ 0.    ,  0.    ,  0.    ,  1.    ]])"
+      ]
+     },
+     "execution_count": 17,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "reachy.r_arm.forward_kinematics(list(right_angle_position.values())[:-1])"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "With this result, we can tell that when the right arm is in the right angle position, the right end-effector is 37cm in front of the origin, 20cm to the left and 28cm below the origin.\n",
+    "\n",
+    "As of the rotation matrix, the identity matrix corresponds to the zero position of the robot\n",
+    "\n",
+    "\\begin{bmatrix}\n",
+    "1 & 0 & 0\\\\\n",
+    "0 & 1 & 0\\\\\n",
+    "0 & 0 & 1\\\\\n",
+    "\\end{bmatrix}\n",
+    "\n",
+    "which is when the hand is facing toward the bottom.\n",
+    "\n",
+    "Here we obtained the rotation matrix\n",
+    "\n",
+    "\\begin{bmatrix}\n",
+    "0 & 0 & -1\\\\\n",
+    "0 & 1 & 0\\\\\n",
+    "1 & 0 & 0\\\\\n",
+    "\\end{bmatrix}\n",
+    "\n",
+    "We can use scipy to understand what this matrix represents."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 44,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from scipy.spatial.transform import Rotation as R\n",
+    "import numpy as np"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 41,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "array([  0., -90.,   0.])"
+      ]
+     },
+     "execution_count": 41,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "R.from_matrix([\n",
+    "    [0, 0, -1],\n",
+    "    [0, 1, 0],\n",
+    "    [1, 0, 0],\n",
+    "]).as_euler('xyz', degrees=True)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "So scipy tells us that a rotation of -90° along the *y* axis has been made to get this matrix, which is coherent with the result because having the hand facing forward corresponds to this rotation according to Reachy's *xyz* axis that we saw above."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Inverse kinematics"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Knowing where you arm is located in the 3D space can be useful but most of the time what you want is to move the arm in cartesian coordinates. You want to have the possibility to say: “move your hand to [x, y, z] with a 90° rotation around the Y axis”.\n",
+    "\n",
+    "This is what inverse kinematics does. We have provided a method to help you with that. You need to give it a 4x4 target pose, like the one given by the forward kinematics, and an initial joint state.\n",
+    "\n",
+    "To make this more concrete, let's first try with a simple example. We will make the hand of the robot going from a point A to a point B in 3D space. You always have to provide poses to the inverse kinematics that are actually reachable by the robot.\n",
+    "\n",
+    "For our starting point, let's imagine a point in front of the robot right shoulder and slightly below. With Reachy coordinate system, we can define such a point with the following coordinates:\n",
+    "\n",
+    "\\begin{equation} A =\n",
+    "\\begin{pmatrix}\n",
+    "0.3 & -0.2 & -0.3\n",
+    "\\end{pmatrix}\n",
+    "\\end{equation}\n",
+    "\n",
+    "For our end point we will stay in a parallel plan in front of the robot (we keep the same x) and move to the upper left (20cm up and 20cm left). This gives us a B point such that:\n",
+    "\n",
+    "\\begin{equation} B =\n",
+    "\\begin{pmatrix}\n",
+    "0.3 & 0.0 & -0.1\n",
+    "\\end{pmatrix}\n",
+    "\\end{equation}\n",
+    "\n",
+    "But having the 3D position is not enough to design a pose. You also need to provide the 3D orientation via a rotation matrix. The rotation matrix is often the tricky part when building a target pose matrix.\n",
+    "\n",
+    "Keep in mind that the identity rotation matrix corresponds to the zero position of the robot which is when the hand is facing toward the bottom. So if we want the hand facing forward when going from A to B, we need to rotate it from -90° around the y axis, as we saw in the forward kinematics part.\n",
+    "\n",
+    "We know from before which rotation matrix corresponds to this rotation, but we can use scipy again to generate the rotation matrix for given rotations."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 48,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "[[ 0. -0. -1.]\n",
+      " [ 0.  1. -0.]\n",
+      " [ 1.  0.  0.]]\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(np.around(R.from_euler('y', np.deg2rad(-90)).as_matrix(), 3))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "We got the rotation matrix that we expected! \n",
+    "\n",
+    "As mentionned, building the pose matrix can be hard, so don't hesitate to use scipy to build your rotation matrix. You can also move the arm with your hand where you want it to be and use the forward kinematics to get an approximation of the target pose matrix you would give to the inverse kinematics."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Here, having the rotation matrix and the 3D positions for our points A and B, we can build both target pose matrices. "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 51,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "A = np.array([\n",
+    "  [0, 0, -1, 0.3],\n",
+    "  [0, 1, 0, -0.2],  \n",
+    "  [1, 0, 0, -0.3],\n",
+    "  [0, 0, 0, 1],  \n",
+    "])\n",
+    "\n",
+    "B = np.array([\n",
+    "  [0, 0, -1, 0.3],\n",
+    "  [0, 1, 0, 0],  \n",
+    "  [1, 0, 0, -0.1],\n",
+    "  [0, 0, 0, 1],  \n",
+    "])"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "*inverse_kinematics()* takes one optional argument, *q0*, which is the starting point of the inverse kinematics computation. If no *q0* is given, *q0* is considered to be equal to the present joints position."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Inverse kinematics is a really powerful way to define motions in coordinate systems that fits better with the defintion of many tasks (grasp the bottle in (x, y, z) for instance). Yet, this approach has also some important limitations.\n",
+    "\n",
+    "It's important to understand that while the forward kinematics has a unique and well defined solution, the inverse kinematics is a much harder and ill defined problem. A Right Arm with a Gripper has 8 Degrees Of Freedom (8 motors) meaning that you may have multiple solutions to reach the same 3D point in space.\n",
+    "\n",
+    "Because the inverse kinematics algorithm used is based on optimisation techniques, giving a starting point *q0* may have a tremendous influence on the final result.\n",
+    "\n",
+    "Now let's use the inverse kinematics to move between our two points A and B! We will consider that the starting point is the right angled position that we used before, then the arm will go to A and finish at B. "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 61,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "joint_pos_A = reachy.r_arm.inverse_kinematics(A, q0=np.deg2rad(list(right_angle_position.values())[:-1]))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 76,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "joint_pos_B = reachy.r_arm.inverse_kinematics(B, q0=np.deg2rad(list(right_angle_position.values())[:-1]))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 77,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# put the joints in stiff mode\n",
+    "for j in reachy.joints[8:16]:\n",
+    "    j.compliant = False"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 73,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# use the goto function\n",
+    "reachy.goto({getattr(reachy,j.name): pos for j,pos in zip(reachy.joints[8:16], joint_pos_A)}, duration=2.0)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 78,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "reachy.goto({getattr(reachy,j.name): pos for j,pos in zip(reachy.joints[8:16], joint_pos_B)}, duration=2.0)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 79,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# put the joints back to compliant mode\n",
+    "# don't forget to put your hand below the arm to prevent it from falling hard!\n",
+    "for j in reachy.joints[8:16]:\n",
+    "    j.compliant = True"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "That's it! Now you know everything on Reachy's kinematics!"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.8.5"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/notebooks/Safety.ipynb b/notebooks/Safety.ipynb
new file mode 100644
index 0000000..12ca4b8
--- /dev/null
+++ b/notebooks/Safety.ipynb
@@ -0,0 +1,274 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Safety first!"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "In this notebook we will talk about safety, for the user and for Reachy."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "First, check that Reachy is correctly attached to its metal support and that the support is well fixed to its table."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The four screws shown below must be well tightened.\n",
+    "\n",
+    "<img src=\"https://raw.githubusercontent.com/pollen-robotics/reachy-sdk/notebooks_documentation/notebooks/images/safety/reachy_back.jpeg?token=AHZJ5IFRHGYFOYMDMFEC2LTAMG53C\" alt=\"drawing\" width=\"300\"/>"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Turning on/off the motors"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The power switch for Reachy's motors is placed in its back.\n",
+    "\n",
+    "<img src=\"https://raw.githubusercontent.com/pollen-robotics/reachy-sdk/notebooks_documentation/notebooks/images/safety/power_button.jpeg?token=AHZJ5IBU7TWFKK3YWI2SNK3AMG44W\" alt=\"drawing\" width=\"300\"/>\n",
+    "\n",
+    "This will only turn on/off Reachy's motors and not the computer inside the robot."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Don't harm yourself..."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Even though there is little chance that you get hurt using Reachy, you must be aware of the working space of Reachy, the positions it can reach. \n",
+    "\n",
+    "We recommend that before you start programing it, move both Reachy's arms with your hands to get a sense of its working space so that you won't get surprised when you actually send it commands."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## and don't harm Reachy!"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "There are a few things you need to know to make sure that your Reachy doesn't get damaged when using it."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Don't stay in stiff mode if you're not moving the robot. "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "As mentionned in the [Joint_control.ipynb noteboook](https://github.com/pollen-robotics/reachy-sdk/blob/notebooks_documentation/notebooks/Joint%20control.ipynb), the goal positions of the joints are only used when the motors are in stiff mode. In stiff mode, you can hear a small crackle and the joints can't be moved by hands.\n",
+    "\n",
+    "In this mode, the motors use their maximum torque to maintain their present position until a goal position is sent.\n",
+    "\n",
+    "Let's put Reachy's joints in stiff mode."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from reachy_sdk import ReachySDK"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "reachy = ReachySDK(host='localhost')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "for joint in reachy.joints:\n",
+    "    joint.compliant = False"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "You should hear a small noise coming from the motors, it's totally normal when they are in stiff mode.\n",
+    "\n",
+    "Try to move the arms with your hands, you should not be able to move them and you should feel the resitance applied by the motors to stay in their position. \n",
+    "\n",
+    "Now let's turn back the joints to compliant mode."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "for joint in reachy.joints:\n",
+    "    joint.compliant = True"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "#### What you need to keep in mind"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "You must be careful not to let the joints in stiff mode when you're not using the robot.\n",
+    "\n",
+    "If an arm is lifted or if the neck is lowered, maintaining the position in stiff mode will be really demanding becuase the motors would have to compensate the gravity and they could get damaged.\n",
+    "\n",
+    "You can make the analogy with a human. If we ask you to keep stretched out arms, after a certain time it will be painful. So is the case for the joints of the robot. "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Be aware of obstacles"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "When you are sending movements instructions to Reachy, be careful to obstacles. \n",
+    "\n",
+    "For example, when you are asking to an arm to go between two positions, it will try to do it as hard as it can whether or not there is something blocking its way. Also when you are moving both arms simultaneously, there are no safety measures implemented to prevent them from hitting each other. \n",
+    "\n",
+    "Nothing will also prevent Reachy's arms from hitting its chest if you ask them to.\n",
+    "\n",
+    "If situations like these happen, don't hesitate to turn off the motors so that Reachy's motors will stop trying to reach a position they can't get."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Check the temperatures"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Reachy's motors will heat when you are using its joints so you should manage the motors temperatures.\n",
+    "\n",
+    "The temperatures of each motor can be accessed using ReachySDK."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "l_shoulder_pitch joint has temperature 38.0 Celsius degrees.\n",
+      "l_shoulder_roll joint has temperature 39.0 Celsius degrees.\n",
+      "l_arm_yaw joint has temperature 40.0 Celsius degrees.\n",
+      "l_elbow_pitch joint has temperature 39.0 Celsius degrees.\n",
+      "l_forearm_yaw joint has temperature 34.0 Celsius degrees.\n",
+      "l_wrist_pitch joint has temperature 37.0 Celsius degrees.\n",
+      "l_wrist_roll joint has temperature 36.0 Celsius degrees.\n",
+      "l_gripper joint has temperature 37.0 Celsius degrees.\n",
+      "r_shoulder_pitch joint has temperature 39.0 Celsius degrees.\n",
+      "r_shoulder_roll joint has temperature 40.0 Celsius degrees.\n",
+      "r_arm_yaw joint has temperature 39.0 Celsius degrees.\n",
+      "r_elbow_pitch joint has temperature 39.0 Celsius degrees.\n",
+      "r_forearm_yaw joint has temperature 34.0 Celsius degrees.\n",
+      "r_wrist_pitch joint has temperature 37.0 Celsius degrees.\n",
+      "r_wrist_roll joint has temperature 36.0 Celsius degrees.\n",
+      "r_gripper joint has temperature 36.0 Celsius degrees.\n",
+      "l_antenna joint has temperature 30.0 Celsius degrees.\n",
+      "r_antenna joint has temperature 30.0 Celsius degrees.\n",
+      "neck_disk_top joint has temperature 25.4375 Celsius degrees.\n",
+      "neck_disk_middle joint has temperature 25.3125 Celsius degrees.\n",
+      "neck_disk_bottom joint has temperature 25.375 Celsius degrees.\n"
+     ]
+    }
+   ],
+   "source": [
+    "for joint in reachy.joints:\n",
+    "    print(f'{joint.name} joint has temperature {joint.temperature} Celsius degrees.')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "There are two important temperatures constants you need to know, their values depend on Reachy's part:\n",
+    "\n",
+    "* **fan trigger temperature**: temperature at which the motor will start to get hot and the matching fan will be turned on. The fans allow to work longer with hot joints but enventually the temperature will keep rising if the joints keep being sollicitated. On Reachy's arms: 45°C, on Reachy's neck: 35°C.\n",
+    "\n",
+    "\n",
+    "* **shutdown temperature**: when this temperature is reached, the motor will normally shutdown and stop working until it has cooled down. This is a precaution measure to protect the motor. On Reachy's arms: 55°C, on Reachy's neck: 50°C."
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.8.5"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/notebooks/camera.ipynb b/notebooks/camera.ipynb
new file mode 100644
index 0000000..b40ae4d
--- /dev/null
+++ b/notebooks/camera.ipynb
@@ -0,0 +1,89 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "%matplotlib inline\n",
+    "\n",
+    "from matplotlib import pyplot as plt"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from reachy_sdk import ReachySDK\n",
+    "\n",
+    "robot = ReachySDK(host='192.168.86.43')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<matplotlib.image.AxesImage at 0x135d32b80>"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "import cv2 as cv\n",
+    "\n",
+    "plt.figure()\n",
+    "plt.imshow(cv.cvtColor(robot.left_camera.last_frame, cv.COLOR_BGR2RGB))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.9.2"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/notebooks/fan.ipynb b/notebooks/fan.ipynb
new file mode 100644
index 0000000..d47e55b
--- /dev/null
+++ b/notebooks/fan.ipynb
@@ -0,0 +1,109 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {
+    "scrolled": false
+   },
+   "outputs": [],
+   "source": [
+    "from reachy_sdk import ReachySDK\n",
+    "\n",
+    "robot = ReachySDK(host='172.16.20.4')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[<Fan name=\"r_shoulder_fan\" state=\"off\">,\n",
+       " <Fan name=\"r_elbow_fan\" state=\"off\">,\n",
+       " <Fan name=\"r_wrist_fan\" state=\"off\">]"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "robot.fans"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "for fan in robot.fans:\n",
+    "    fan.on()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[<Fan name=\"r_shoulder_fan\" state=\"on\">,\n",
+       " <Fan name=\"r_elbow_fan\" state=\"on\">,\n",
+       " <Fan name=\"r_wrist_fan\" state=\"on\">]"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "robot.fans"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "for fan in robot.fans:\n",
+    "    fan.off()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.9.2"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/notebooks/fk-ik-example.ipynb b/notebooks/fk-ik-example.ipynb
new file mode 100644
index 0000000..7d67a54
--- /dev/null
+++ b/notebooks/fk-ik-example.ipynb
@@ -0,0 +1,105 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {
+    "scrolled": false
+   },
+   "outputs": [],
+   "source": [
+    "from reachy_sdk import ReachySDK\n",
+    "\n",
+    "robot = ReachySDK(host='192.168.86.43')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "array([[ 0.98344421,  0.18118948,  0.00280215, -0.00553341],\n",
+       "       [-0.17639553,  0.9536539 ,  0.24378036,  0.18776011],\n",
+       "       [ 0.04149815, -0.24023867,  0.96982642, -0.64720705],\n",
+       "       [ 0.        ,  0.        ,  0.        ,  1.        ]])"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "import numpy as np\n",
+    "\n",
+    "target = robot.l_arm.forward_kinematics()\n",
+    "target"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[3.2143562775157584,\n",
+       " 1.011946006907061,\n",
+       " -6.7869491179635295,\n",
+       " -4.817568237200579,\n",
+       " -3.3073609949112917,\n",
+       " -0.9012769699058041,\n",
+       " -14.61470930781741]"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "sol = robot.l_arm.inverse_kinematics(target)\n",
+    "sol"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.9.2"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/notebooks/force-sensor.ipynb b/notebooks/force-sensor.ipynb
new file mode 100644
index 0000000..c87f9bf
--- /dev/null
+++ b/notebooks/force-sensor.ipynb
@@ -0,0 +1,65 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": false
+   },
+   "outputs": [],
+   "source": [
+    "from reachy_sdk import ReachySDK\n",
+    "\n",
+    "robot = ReachySDK(host='172.16.20.4')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[<ForceSensor name=\"r_force_gripper\" force=\"-216.35980224609375\">]"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "robot.force_sensors"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.9.2"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/notebooks/goto.ipynb b/notebooks/goto.ipynb
new file mode 100644
index 0000000..6d3bca0
--- /dev/null
+++ b/notebooks/goto.ipynb
@@ -0,0 +1,104 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from reachy_sdk import ReachySDK\n",
+    "\n",
+    "robot = ReachySDK(host='192.168.86.43')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "robot.l_gripper.compliant = False\n",
+    "robot.r_gripper.compliant = False"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "robot.goto({\n",
+    "    robot.l_gripper: -20,\n",
+    "    robot.r_gripper: 20,\n",
+    "}, duration=1.0)\n",
+    "robot.goto({\n",
+    "    robot.l_gripper: 20,\n",
+    "    robot.r_gripper: -20,\n",
+    "}, duration=1.0)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from reachy_sdk.trajectory.interpolation import InterpolationMode\n",
+    "\n",
+    "await robot.goto_async({\n",
+    "    robot.l_gripper: -20,\n",
+    "    robot.r_gripper: 20,\n",
+    "}, duration=1.0, interpolation_mode=InterpolationMode.MINIMUM_JERK)\n",
+    "await robot.goto_async({\n",
+    "    robot.l_gripper: 20,\n",
+    "    robot.r_gripper: -20,\n",
+    "}, duration=1.0, interpolation_mode=InterpolationMode.MINIMUM_JERK)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "robot.l_gripper.compliant = True\n",
+    "robot.r_gripper.compliant = True"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.9.2"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/notebooks/images/joint_control/arm_schematic.png b/notebooks/images/joint_control/arm_schematic.png
new file mode 100644
index 0000000..f1c71e0
Binary files /dev/null and b/notebooks/images/joint_control/arm_schematic.png differ
diff --git a/notebooks/images/joint_control/dynamixel_speed.png b/notebooks/images/joint_control/dynamixel_speed.png
new file mode 100644
index 0000000..88105be
Binary files /dev/null and b/notebooks/images/joint_control/dynamixel_speed.png differ
diff --git a/notebooks/images/joint_control/orbita.png b/notebooks/images/joint_control/orbita.png
new file mode 100644
index 0000000..50695e5
Binary files /dev/null and b/notebooks/images/joint_control/orbita.png differ
diff --git a/notebooks/images/kinematics/arm_axis.png b/notebooks/images/kinematics/arm_axis.png
new file mode 100644
index 0000000..94da5ac
Binary files /dev/null and b/notebooks/images/kinematics/arm_axis.png differ
diff --git a/notebooks/images/kinematics/eef.png b/notebooks/images/kinematics/eef.png
new file mode 100644
index 0000000..26c0ca1
Binary files /dev/null and b/notebooks/images/kinematics/eef.png differ
diff --git a/notebooks/images/kinematics/interpolation.png b/notebooks/images/kinematics/interpolation.png
new file mode 100644
index 0000000..f4159f9
Binary files /dev/null and b/notebooks/images/kinematics/interpolation.png differ
diff --git a/notebooks/images/kinematics/right_arm_kinematic_model.png b/notebooks/images/kinematics/right_arm_kinematic_model.png
new file mode 100644
index 0000000..83a7e58
Binary files /dev/null and b/notebooks/images/kinematics/right_arm_kinematic_model.png differ
diff --git a/notebooks/images/safety/power_button.jpeg b/notebooks/images/safety/power_button.jpeg
new file mode 100644
index 0000000..adab645
Binary files /dev/null and b/notebooks/images/safety/power_button.jpeg differ
diff --git a/notebooks/images/safety/reachy_back.jpeg b/notebooks/images/safety/reachy_back.jpeg
new file mode 100644
index 0000000..36885ab
Binary files /dev/null and b/notebooks/images/safety/reachy_back.jpeg differ
diff --git a/notebooks/images/safety/reachy_eef.gif b/notebooks/images/safety/reachy_eef.gif
new file mode 100644
index 0000000..4ca0d02
Binary files /dev/null and b/notebooks/images/safety/reachy_eef.gif differ
diff --git a/notebooks/joint-example.ipynb b/notebooks/joint-example.ipynb
new file mode 100644
index 0000000..436c1a5
--- /dev/null
+++ b/notebooks/joint-example.ipynb
@@ -0,0 +1,161 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": false
+   },
+   "outputs": [],
+   "source": [
+    "from reachy_sdk import ReachySDK\n",
+    "\n",
+    "robot = ReachySDK(host='127.0.0.1')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "robot.l_shoulder_pitch"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "robot.joints"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "robot.l_shoulder_pitch.goal_position = 12"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "robot.l_shoulder_pitch.registers()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "robot.l_shoulder_pitch.present_position"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "robot.l_shoulder_pitch.temperature"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "robot.l_shoulder_pitch"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "robot.r_gripper.compliant = False"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "robot.r_gripper.goal_position = 0.24"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "robot.r_gripper.pid"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "robot.r_gripper.pid = (1, 1, 32, 32)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "for j in robot.joints:\n",
+    "    print(j.name, j.present_position)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.9.2"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/reachy_sdk/__init__.py b/reachy_sdk/__init__.py
index ae38ab7..aeffe51 100644
--- a/reachy_sdk/__init__.py
+++ b/reachy_sdk/__init__.py
@@ -1,1 +1,5 @@
+"""Reachy SDK package.
+
+Provides remote access (via socket) to a Reachy robot.
+"""
 from .reachy_sdk import ReachySDK  # noqa: F401
diff --git a/reachy_sdk/arm.py b/reachy_sdk/arm.py
new file mode 100644
index 0000000..cdb06f0
--- /dev/null
+++ b/reachy_sdk/arm.py
@@ -0,0 +1,177 @@
+"""Reachy Arm module.
+
+Handles all specific method to an Arm (left and/or right) especially:
+- the forward kinematics
+- the inverse kinematics
+"""
+
+from abc import ABC
+from typing import List, Optional, Set
+
+import numpy as np
+
+from reachy_sdk_api.arm_kinematics_pb2_grpc import ArmKinematicsStub
+from reachy_sdk_api.arm_kinematics_pb2 import ArmEndEffector, ArmFKRequest, ArmIKRequest, ArmJointPosition, ArmSide
+from reachy_sdk_api.kinematics_pb2 import joint__pb2
+from reachy_sdk_api.arm_kinematics_pb2 import kinematics__pb2
+
+from .joint import Joint
+
+# Circumvent https://github.com/grpc/grpc/issues/18139
+JointId = joint__pb2.JointId
+JointPosition = kinematics__pb2.JointPosition
+Matrix4x4 = kinematics__pb2.Matrix4x4
+
+
+class Arm(ABC):
+    """Arm abstract class used for both left/right arms.
+
+    It exposes the kinematics of the arm:
+    - you can access the joints actually used in the kinematic chain,
+    - you can compute the forward and inverse kinematics
+    """
+
+    def __init__(self, joints: List[Joint], grpc_channel) -> None:
+        """Set up the arm with its kinematics."""
+        self._kin_stub = ArmKinematicsStub(grpc_channel)
+
+        self.joints = [j for j in joints if j.name in self._required_joints]
+
+        if len(self.joints) != len(self._required_joints):
+            raise ValueError(f'Required joints not found {self._required_joints}')
+
+        self.kinematics_chain = [j for j in self.joints if j.name in self._kinematics_chain]
+
+    @property
+    def _side(self) -> str:
+        ...
+
+    def forward_kinematics(self, joints_position: Optional[List[float]] = None) -> np.ndarray:
+        """Compute the forward kinematics of the arm.
+
+        It will return the pose 4x4 matrix (as a numpy array) expressed in Reachy coordinate systems.
+        You can either specify a given joints position, otherwise it will use the current robot position.
+        """
+        if joints_position is None:
+            joints_position = [j.present_position for j in self.kinematics_chain]
+
+        if isinstance(joints_position, np.ndarray) and len(joints_position.shape) > 1:
+            raise ValueError('Vectorized kinematics not supported!')
+
+        pos = np.deg2rad(joints_position)
+
+        if len(pos) != len(self._kinematics_chain):
+            raise ValueError(
+                f'joints_position should be length {len(self._kinematics_chain)} (got {len(pos)} instead)!'
+            )
+
+        req = ArmFKRequest(
+            arm_position=ArmJointPosition(
+                side=self._arm_side,
+                positions=self._joint_position_from_pos(pos),
+            ),
+        )
+        resp = self._kin_stub.ComputeArmFK(req)
+        if not resp.success:
+            raise ValueError(f'No solution found for the given joints ({joints_position})!')
+
+        return np.array(resp.end_effector.pose.data).reshape((4, 4))
+
+    def inverse_kinematics(self, target: np.ndarray, q0: Optional[List[float]] = None) -> List[float]:
+        """Compute the inverse kinematics of the arm.
+
+        Given a pose 4x4 target matrix (as a numpy array) expressed in Reachy coordinate systems,
+        it will try to compute a joint solution to reach this target (or get close).
+
+        It will raise a ValueError if no solution are found.
+
+        You can also specify a basic joint configuration as a prior for the solution.
+        """
+        if target.shape != (4, 4):
+            raise ValueError('target shape should be (4, 4) (got {target.shape} instead)!')
+
+        if q0 is not None and (len(q0) != len(self._kinematics_chain)):
+            raise ValueError(f'q0 should be length {len(self._kinematics_chain)} (got {len(q0)} instead)!')
+
+        if isinstance(q0, np.ndarray) and len(q0.shape) > 1:
+            raise ValueError('Vectorized kinematics not supported!')
+
+        req_params = {
+            'target': ArmEndEffector(
+                side=self._arm_side,
+                pose=Matrix4x4(data=target.flatten().tolist()),
+            )
+        }
+
+        if q0 is not None:
+            req_params['q0'] = self._joint_position_from_pos(q0)
+
+        req = ArmIKRequest(**req_params)
+        resp = self._kin_stub.ComputeArmIK(req)
+
+        if not resp.success:
+            raise ValueError(f'No solution found for the given target ({target})!')
+
+        return np.rad2deg(resp.arm_position.positions.positions).tolist()
+
+    @property
+    def _kinematics_chain(self) -> List[str]:
+        ...
+
+    @property
+    def _required_joints(self) -> Set[str]:
+        ...
+
+    @property
+    def _arm_side(self):
+        return ArmSide.LEFT if self._side == 'left' else ArmSide.RIGHT
+
+    def _joint_position_from_pos(self, joints_position: List[float]) -> ArmJointPosition:
+        return JointPosition(
+            ids=[JointId(uid=j.uid) for j in self.kinematics_chain],
+            positions=joints_position,
+        )
+
+
+class LeftArm(Arm):
+    """LeftArm class, all the work is actually done by the ABC Arm class.
+
+    It exposes the kinematics of the arm:
+    - you can access the joints actually used in the kinematic chain,
+    - you can compute the forward and inverse kinematics
+    """
+
+    _side = 'left'
+    _kinematics_chain = (
+        'l_shoulder_pitch', 'l_shoulder_roll', 'l_arm_yaw',
+        'l_elbow_pitch', 'l_forearm_yaw',
+        'l_wrist_pitch', 'l_wrist_roll',
+    )
+    _required_joints = {
+        'l_shoulder_pitch', 'l_shoulder_roll', 'l_arm_yaw',
+        'l_elbow_pitch', 'l_forearm_yaw',
+        'l_wrist_pitch', 'l_wrist_roll',
+        'l_gripper',
+    }
+
+
+class RightArm(Arm):
+    """RightArm class, all the work is actually done by the ABC Arm class.
+
+    It exposes the kinematics of the arm:
+    - you can access the joints actually used in the kinematic chain,
+    - you can compute the forward and inverse kinematics
+    """
+
+    _side = 'right'
+    _kinematics_chain = (
+        'r_shoulder_pitch', 'r_shoulder_roll', 'r_arm_yaw',
+        'r_elbow_pitch', 'r_forearm_yaw',
+        'r_wrist_pitch', 'r_wrist_roll',
+    )
+    _required_joints = {
+        'r_shoulder_pitch', 'r_shoulder_roll', 'r_arm_yaw',
+        'r_elbow_pitch', 'r_forearm_yaw',
+        'r_wrist_pitch', 'r_wrist_roll',
+        'r_gripper',
+    }
diff --git a/reachy_sdk/camera.py b/reachy_sdk/camera.py
new file mode 100644
index 0000000..c6ffa9a
--- /dev/null
+++ b/reachy_sdk/camera.py
@@ -0,0 +1,136 @@
+"""Camera Reachy module.
+
+This module lets you access always up-to-date image from the camera.
+The synchronisation is done in background and only started when you need it.
+"""
+
+from enum import Enum
+from typing import Optional
+import cv2 as cv
+import numpy as np
+
+from threading import Event, Thread
+
+from reachy_sdk_api import camera_reachy_pb2, camera_reachy_pb2_grpc
+
+
+class ZoomLevel(Enum):
+    """The zoom level options."""
+
+    ZERO = camera_reachy_pb2.ZoomLevelPossibilities.ZERO
+    IN = camera_reachy_pb2.ZoomLevelPossibilities.IN
+    INTER = camera_reachy_pb2.ZoomLevelPossibilities.INTER
+    OUT = camera_reachy_pb2.ZoomLevelPossibilities.OUT
+
+
+class Camera:
+    """The camera class."""
+
+    def __init__(self,
+                 side: str, stub: camera_reachy_pb2_grpc.CameraServiceStub,
+                 ) -> None:
+        """Set up the camera.
+
+        The sync loop is only started the first time you try to access a frame.
+        This lazy set up allows for not streaming the images when they are not used.
+        """
+        self._initialized = False
+        self._got_img = Event()
+        self._last_frame: Optional[np.ndarray] = None
+
+        self._camera = camera_reachy_pb2.Camera(
+            id=camera_reachy_pb2.CameraId.LEFT if side == 'left' else camera_reachy_pb2.CameraId.RIGHT,
+        )
+
+        self._stub = stub
+
+    @property
+    def last_frame(self) -> np.ndarray:
+        """Return the last retrieved frame."""
+        if not self._initialized:
+            self._start_sync_in_bg()
+
+        assert self._last_frame is not None
+        return self._last_frame
+
+    def wait_for_new_frame(self) -> np.ndarray:
+        """Block until the reception of a new frame."""
+        if not self._initialized:
+            self._start_sync_in_bg()
+
+        self._got_img.wait()
+        self._got_img.clear()
+        return self.last_frame
+
+    def zoom_homing(self) -> bool:
+        """Run a homing to reset zoom position."""
+        resp = self._stub.SendZoomCommand(
+            camera_reachy_pb2.ZoomCommand(
+                camera=self._camera,
+                homing_command=camera_reachy_pb2.ZoomHoming(),
+            ),
+        )
+        return resp.success
+
+    @property
+    def zoom_level(self) -> ZoomLevel:
+        """Get the current zoom level."""
+        resp = self._stub.GetZoomLevel(self._camera)
+        return ZoomLevel(resp.level)
+
+    @zoom_level.setter
+    def zoom_level(self, level: ZoomLevel):
+        if level == ZoomLevel.ZERO:
+            raise ValueError('Can not set zoom level to zero, use homing instead!')
+
+        resp = self._stub.SendZoomCommand(
+            camera_reachy_pb2.ZoomCommand(
+                camera=self._camera,
+                level_command=camera_reachy_pb2.ZoomLevel(
+                    level=level.value,
+                ),
+            ),
+        )
+        if not resp.success:
+            raise ValueError('Could not set new zoom level!')
+
+    @property
+    def zoom_speed(self) -> int:
+        """Get the current zoom speed."""
+        resp = self._stub.GetZoomSpeed(self._camera)
+        return resp.speed
+
+    @zoom_speed.setter
+    def zoom_speed(self, speed: int):
+        if not (4000 <= speed <= 40000):
+            raise ValueError('Speed should be within range (4000, 40000)!')
+
+        resp = self._stub.SendZoomCommand(
+            camera_reachy_pb2.ZoomCommand(
+                camera=self._camera,
+                speed_command=camera_reachy_pb2.ZoomSpeed(
+                    speed=speed,
+                ),
+            ),
+        )
+        if not resp.success:
+            raise ValueError('Could not set new zoom level!')
+
+    def _start_sync_in_bg(self):
+        def poll_img():
+            stream_request = camera_reachy_pb2.StreamImageRequest(
+                request=camera_reachy_pb2.ImageRequest(
+                    camera=self._camera,
+                ),
+            )
+
+            for resp in self._stub.StreamImage(stream_request):
+                buff = np.frombuffer(resp.data, dtype=np.uint8)
+                self._last_frame = cv.imdecode(buff, cv.IMREAD_COLOR)
+                self._got_img.set()
+
+        self._t = Thread(target=poll_img)
+        self._t.daemon = True
+        self._t.start()
+
+        self._got_img.wait()
diff --git a/reachy_sdk/example/visualize_camera.py b/reachy_sdk/example/visualize_camera.py
index dfaf922..0dc545b 100644
--- a/reachy_sdk/example/visualize_camera.py
+++ b/reachy_sdk/example/visualize_camera.py
@@ -17,7 +17,7 @@ def switch_side(side):
 
 
 def run():
-    """Main."""
+    """Run main loop."""
     options = [('grpc.max_send_message_length', 200000), ('grpc.max_receive_message_length', 200000)]
     side = 'right'
     host = 'localhost'
@@ -28,7 +28,7 @@ def run():
             response = stub.GetImage(ros_cam_pb2.Side(side=side))
             img = np.frombuffer(response.data, dtype=np.uint8)
             img = cv.imdecode(img, cv.IMREAD_COLOR)
-            cv.imshow('frame',img)
+            cv.imshow('frame', img)
             if cv.waitKey(1) & 0xFF == ord('s'):
                 side = switch_side(side)
 
diff --git a/reachy_sdk/fan.py b/reachy_sdk/fan.py
new file mode 100644
index 0000000..1332267
--- /dev/null
+++ b/reachy_sdk/fan.py
@@ -0,0 +1,58 @@
+"""This module define the Fan class and method to get/set their state."""
+
+from reachy_sdk_api import fan_pb2, fan_pb2_grpc
+
+
+class Fan:
+    """The Fan class and get/set state methods.
+
+    The Fan class is used to store the up-to-date state of the fan.
+    You can get its current state (check if they were automatically turned on by a temperature limit detection).
+    You can also turn them on/off whenever you want.
+    """
+
+    def __init__(self, name: str, uid: int, stub: fan_pb2_grpc.FanControllerServiceStub) -> None:
+        """Set up the fan."""
+        self._name = name
+        self._uid = uid
+
+        self._stub = stub
+
+    def __repr__(self) -> str:
+        """Clean representation of a fan state."""
+        state = 'on' if self.is_on else 'off'
+        return f'<Fan name="{self.name}" state="{state}">'
+
+    @property
+    def name(self):
+        """Get the name of the fan."""
+        return self._name
+
+    @property
+    def is_on(self):
+        """Check if the fan is on."""
+        resp = self._stub.GetFansState(fan_pb2.FansStateRequest(
+            ids=[fan_pb2.FanId(uid=self._uid)],
+        ))
+        return resp.states[0].on
+
+    def on(self):
+        """Turn the fan on."""
+        self._set_state(on=True)
+
+    def off(self):
+        """Turn the fan off."""
+        self._set_state(on=False)
+
+    def _set_state(self, on: bool):
+        resp = self._stub.SendFansCommands(fan_pb2.FansCommand(
+            commands=[
+                fan_pb2.FanCommand(
+                    id=fan_pb2.FanId(uid=self._uid),
+                    on=on,
+                ),
+            ]
+        ))
+        if not resp.success:
+            state = 'on' if self.is_on else 'off'
+            raise IOError(f'Could not set fan "{self.name}" {state}!')
diff --git a/reachy_sdk/force_sensor.py b/reachy_sdk/force_sensor.py
new file mode 100644
index 0000000..6841d67
--- /dev/null
+++ b/reachy_sdk/force_sensor.py
@@ -0,0 +1,39 @@
+"""This module define the Force Sensor class."""
+
+from reachy_sdk_api.sensor_pb2 import ForceSensorState
+
+
+class ForceSensor:
+    """The Force sensor class.
+
+    The Force Sensor class is used to store the up-to-date force read by the sensor.
+    """
+
+    def __init__(self, name: str, uid: int, state: ForceSensorState) -> None:
+        """Set up the force sensor."""
+        self._name = name
+        self._uid = uid
+
+        self._update_with(state)
+
+    def __repr__(self) -> str:
+        """Clean representation of a force sensor state."""
+        return f'<ForceSensor name="{self.name}" force="{self.force:.2f}">'
+
+    @property
+    def name(self):
+        """Get the name of the force sensor."""
+        return self._name
+
+    @property
+    def uid(self):
+        """Get the name of the force sensor."""
+        return self._uid
+
+    @property
+    def force(self):
+        """Get the current force read by the sensor."""
+        return self._force
+
+    def _update_with(self, state: ForceSensorState):
+        self._force = state.force
diff --git a/reachy_sdk/joint.py b/reachy_sdk/joint.py
index 741939d..62507c1 100644
--- a/reachy_sdk/joint.py
+++ b/reachy_sdk/joint.py
@@ -1,122 +1,112 @@
-import numpy as np
+"""This module define the Joint class (any dynamixel motor or one of orbita's disk) and its registers."""
 
-from threading import Event
-from google.protobuf.wrappers_pb2 import BoolValue, FloatValue
-
-from reachy_sdk_api.joint_command_pb2 import JointCommand
-
-
-class Joint:
-    def __init__(self, name: str, id: int,
-                 present_position: float, present_speed: float, present_load: float, temperature: float,
-                 goal_position: float, speed_limit: float, torque_limit: float,
-                 compliant: bool,
-                 # pid: (float, float, float),
-                 ) -> None:
-        self._name = name
-        self._id = id
-
-        self._fields = {
-            # TODO: Use metaclass instead (look at Django?)
-            'present_position': Field('present_position', present_position),
-            'present_speed': Field('present_speed', present_speed),
-            'present_load': Field('present_load', present_load),
-            'temperature': Field('temperature', temperature),
-
-            'goal_position': Field('goal_position', goal_position, FloatValue),
-            'speed_limit': Field('speed_limit', speed_limit, FloatValue),
-            'torque_limit': Field('torque_limit', torque_limit, FloatValue),
-            'compliant': Field('compliant', compliant, BoolValue),
-        }
+import asyncio
+import threading
+from typing import Any, Dict, List
+
+import numpy as np
 
-    @property
-    def name(self):
-        return self._name
+from google.protobuf.wrappers_pb2 import BoolValue, FloatValue, UInt32Value
 
-    @property
-    def present_position(self):
-        return np.rad2deg(self._fields['present_position'].value)
+from reachy_sdk_api.joint_pb2 import JointId, JointState, JointCommand, PIDValue
 
-    @property
-    def present_speed(self):
-        return np.rad2deg(self._fields['present_speed'].value)
+from .register import MetaRegister, Register
 
-    @property
-    def present_load(self):
-        return self._fields['present_load'].value
 
-    @property
-    def temperature(self):
-        return self._fields['temperature'].value
+class Joint(metaclass=MetaRegister):
+    """The Joint class represents (any dynamixel motor or one of orbita's disk) and its registers.
 
-    @property
-    def goal_position(self):
-        return np.rad2deg(self._fields['goal_position'].value)
+    The Joint class is used to store the up-to-date state of the joint, especially the RO registers:
+        - its name and uid (resp. str and int) which will never change
+        - its current position (in degree)
+        - the current speed and load are presently not updated as the value given by the motor is unreliable
+        - its current temperature (in degree celsius)
 
-    @goal_position.setter
-    def goal_position(self, value):
-        self._fields['goal_position'].request_value_update(np.deg2rad(value))
+    Similarly, when setting a new value to one of its RW register.
+    The Joint is responsible to inform the robot that some commands need to be sent.
+    The RW registers are:
+        - set the compliance on/off (boolean)
+        - goal position (in degree)
+        - speed limit (in degree per second)
+        - the torque limit (in %)
+        - its pid (refer to the different types of motor to have a better understanding of the gain expected range)
+    """
 
-    @property
-    def speed_limit(self):
-        return np.rad2deg(self._fields['speed_limit'].value)
+    name = Register(readonly=True, type=str)
+    uid = Register(readonly=True, type=UInt32Value)
 
-    @speed_limit.setter
-    def speed_limit(self, value):
-        self._fields['speed_limit'].request_value_update(np.deg2rad(value))
+    present_position = Register(readonly=True, type=FloatValue, conversion=(np.deg2rad, np.rad2deg))
+    present_speed = Register(readonly=True, type=FloatValue, conversion=(np.deg2rad, np.rad2deg))
+    present_load = Register(readonly=True, type=FloatValue)
+    temperature = Register(readonly=True, type=FloatValue)
 
-    @property
-    def torque_limit(self):
-        return self._fields['torque_limit'].value
+    compliant = Register(readonly=False, type=BoolValue)
+    goal_position = Register(readonly=False, type=FloatValue, conversion=(np.deg2rad, np.rad2deg))
+    speed_limit = Register(readonly=False, type=FloatValue, conversion=(np.deg2rad, np.rad2deg))
+    torque_limit = Register(readonly=False, type=FloatValue)
 
-    @torque_limit.setter
-    def torque_limit(self, value):
-        self._fields['torque_limit'].request_value_update(value)
+    pid = Register(readonly=False, type=PIDValue)
 
-    @property
-    def compliant(self):
-        return self._fields['compliant'].value
+    def __init__(self, initial_state: JointState) -> None:
+        """Set up the joint with its initial state retrieved from the robot."""
+        self._state: Dict[str, Any] = {}
+        self._sync_lock = threading.Lock()
 
-    @compliant.setter
-    def compliant(self, value):
-        if not value:
-            self.goal_position = self.present_position
-        self._fields['compliant'].request_value_update(value)
+        self._update_with(initial_state)
 
-    def _need_sync(self) -> bool:
-        for field in self._fields.values():
-            if field.sync_evt.is_set():
-                return True
+    def __repr__(self):
+        """Clean representation of a joint basic state."""
+        mode = "compliant" if self.compliant else "stiff"
+        return f'<Joint name="{self.name}" pos="{self.present_position:.2f}" mode="{mode}">'
 
-        return False
+    def registers(self):
+        """Return a dict[name, value] of all the Joint registers."""
+        return {
+            field: getattr(self, field)
+            for field in self._state.keys()
+        }
 
-    def _pop_sync_command(self) -> JointCommand:
-        args = {'id': self._id}
+    def __getitem__(self, field: str) -> Any:
+        """Access a specific register of the Joint using the joint[register_name] notation."""
+        return self._state[field]
 
-        for name, field in self._fields.items():
-            if field.sync_evt.is_set():
-                args[name] = field.protobuf_value_type(value=field.value)
-                field.sync_evt.clear()
+    def __setitem__(self, field: str, value: Any):
+        """Set a new value for a register of the Joint using the joint[register_name] = value notation."""
+        self._state[field] = value
 
-        return JointCommand(**args)
+        with self._sync_lock:
+            self._register_needing_sync.append(field)
+            self._need_sync.set()
 
+    def _setup_sync_loop(self):
+        """Set up the async synchronisation loop.
 
-class Field:
-    def __init__(self, name, value, protobuf_value_type=None) -> None:
-        self.name = name
-        self.value = value
-        self.protobuf_value_type = protobuf_value_type
+        The setup is done separately, as the async Event should be created in the same EventLoop than it will be used.
 
-        self.sync_evt = Event()
+        The _need_sync Event is used to inform the robot that some data need to be pushed to the real robot.
+        The _register_needing_sync stores a list of the register that need to be synced.
+        """
+        self._need_sync = asyncio.Event()
+        self._register_needing_sync: List[str] = []
 
-    def __repr__(self) -> str:
-        return f'<"{camelCase(self.name)}"={self.value}>'
+    def _update_with(self, new_state: JointState):
+        """Update the joint with a newly received (partial) state received from the gRPC server."""
+        for field, value in new_state.ListFields():
+            self._state[field.name] = value
 
-    def request_value_update(self, value) -> None:
-        if value != self.value:
-            self.value = value
-            self.sync_evt.set()
+    def _pop_command(self) -> JointCommand:
+        """Create a gRPC command from the registers that need to be synced."""
+        values = {
+            'id': JointId(uid=self.uid)
+        }
+        values.update({
+            reg: self._state[reg]
+            for reg in self._register_needing_sync
+        })
+        command = JointCommand(**values)
 
+        with self._sync_lock:
+            self._register_needing_sync.clear()
+            self._need_sync.clear()
 
-def camelCase(st):
-    return ''.join(x for x in st.title() if x.isalnum())
+        return command
diff --git a/reachy_sdk/reachy_sdk.py b/reachy_sdk/reachy_sdk.py
index 975740a..67e80d9 100644
--- a/reachy_sdk/reachy_sdk.py
+++ b/reachy_sdk/reachy_sdk.py
@@ -1,277 +1,298 @@
-"""Reachy SDK."""
+"""ReachySDK package.
+
+This package provides remote access (via socket) to a Reachy robot.
+It automatically handles the synchronization with the robot.
+In particular, you can easily get an always up-to-date robot state (joint positions, sensors value).
+You can also send joint commands, compute forward or inverse kinematics.
+
+"""
+
+import asyncio
+import threading
 import time
-from typing import List
-import cv2 as cv
-from google.protobuf.wrappers_pb2 import FloatValue
+from concurrent.futures import ThreadPoolExecutor
+from typing import Dict, List, Optional
+
 import numpy as np
 
 import grpc
 from google.protobuf.empty_pb2 import Empty
 
-from reachy_sdk_api import joint_command_pb2_grpc,  joint_state_pb2_grpc, kinematics_pb2_grpc
-from reachy_sdk_api import camera_reachy_pb2_grpc, load_sensor_pb2_grpc
-from reachy_sdk_api import arm_kinematics_pb2_grpc, zoom_command_pb2_grpc
-from reachy_sdk_api import cartesian_command_pb2_grpc, orbita_kinematics_pb2_grpc
-
-from reachy_sdk_api.joint_state_pb2 import JointStateField, JointRequest, StreamAllJointsRequest
-from reachy_sdk_api.joint_command_pb2 import JointCommand, MultipleJointsCommand
-from reachy_sdk_api.camera_reachy_pb2 import Side as CamSide
-from reachy_sdk_api.load_sensor_pb2 import Side as LoadSide
-from reachy_sdk_api.arm_kinematics_pb2 import ArmEndEffector, ArmJointsPosition, ArmSide
-from reachy_sdk_api.kinematics_pb2 import JointsPosition, Matrix4x4
-from reachy_sdk_api.zoom_command_pb2 import ZoomCommand, ZoomSpeed
-from reachy_sdk_api.orbita_kinematics_pb2 import Point
-from reachy_sdk_api.cartesian_command_pb2 import FullBodyCartesianCommand
-from reachy_sdk_api.kinematics_pb2 import MinjerkRequest
+from reachy_sdk_api import camera_reachy_pb2_grpc
+from reachy_sdk_api import joint_pb2, joint_pb2_grpc
+from reachy_sdk_api import fan_pb2_grpc
+from reachy_sdk_api import sensor_pb2, sensor_pb2_grpc
 
+from .arm import LeftArm, RightArm
+from .camera import Camera
+from .fan import Fan
+from .force_sensor import ForceSensor
 from .joint import Joint
+from .trajectory.interpolation import InterpolationMode
 
 
-side_to_proto = {'left': ArmSide.LEFT, 'right': ArmSide.RIGHT}
+class ReachySDK:
+    """The ReachySDK class handles the connection with your robot.
 
+    It holds:
+    - all joints (can be accessed directly via their name or via the joints list).
+    - all force sensors (can be accessed directly via their name or via the force_sensors list).
+    - all fans (can be accessed directly via their name or via the fans list).
 
-class ReachySDK:
-    def __init__(self, host: str = 'localhost', port: int = 50055, sync_freq: float = 100) -> None:
-        options = [('grpc.max_send_message_length', 200000), ('grpc.max_receive_message_length', 200000)]
-        self._channel = grpc.insecure_channel(f'{host}:{port}', options=options)
-        self._joint_state_stub = joint_state_pb2_grpc.JointStateServiceStub(self._channel)
-        self._joint_command_stub = joint_command_pb2_grpc.JointCommandServiceStub(self._channel)
-        self._load_sensor_stub = load_sensor_pb2_grpc.LoadServiceStub(self._channel)
-        self._camera_stub = camera_reachy_pb2_grpc.CameraServiceStub(self._channel)
-        self._arm_kinematics_stub = arm_kinematics_pb2_grpc.ArmKinematicStub(self._channel)
-        self._zoom_controller_stub = zoom_command_pb2_grpc.ZoomControllerServiceStub(self._channel)
-        self._orbita_stub = orbita_kinematics_pb2_grpc.OrbitaKinematicStub(self._channel)
-        self._cartesian_stub = cartesian_command_pb2_grpc.CartesianCommandServiceStub(self._channel)
-        self._kinematics_stub = kinematics_pb2_grpc.KinematicsServiceStub(self._channel)
+    The synchronisation with the robot is automatically launched at instanciation and is handled in background automatically.
+    """
+
+    def __init__(self, host: str, sdk_port: int = 50055, camera_port: int = 50057) -> None:
+        """Set up the connection with the robot."""
+        self._host = host
+        self._sdk_port = sdk_port
+        self._camera_port = camera_port
+        self._grpc_channel = grpc.insecure_channel(f'{self._host}:{self._sdk_port}')
 
         self.joints: List[Joint] = []
-        self._get_initial_joint_state()
-
-        self._sync_freq = sync_freq
-        self._run_sync_loop_in_bg()
-
-        self.left_image = None
-        self.right_image = None
-
-        self.left_load_sensor = 0
-        self.right_load_sensor = 0
-
-    def _get_initial_joint_state(self) -> None:
-        self.joints.clear()
-
-        motor_names = self._joint_state_stub.GetAllJointNames(Empty())
-
-        for id, name in enumerate(motor_names.names):
-            joint_state = self._joint_state_stub.GetJointState(JointRequest(
-                name=name, requested_fields=[JointStateField.ALL],
-            ))
-            j = Joint(
-                name=joint_state.name,
-                id=id,
-                present_position=joint_state.present_position.value,
-                present_speed=joint_state.present_speed.value,
-                present_load=joint_state.present_load.value,
-                temperature=joint_state.temperature.value,
-                goal_position=joint_state.goal_position.value,
-                speed_limit=joint_state.speed_limit.value,
-                torque_limit=joint_state.torque_limit.value,
-                compliant=joint_state.compliant.value,
-                # pid=joint_state.pid.value,
+        self.fans: List[Fan] = []
+        self.force_sensors: List[ForceSensor] = []
+
+        self._setup_joints()
+        self._setup_arms()
+        self._setup_fans()
+        self._setup_force_sensors()
+        self._setup_cameras()
+
+        self._sync_thread = threading.Thread(target=self._start_sync_in_bg)
+        self._sync_thread.daemon = True
+        self._sync_thread.start()
+
+    def goto(
+        self,
+        goal_positions: Dict[Joint, float],
+        duration: float,
+        starting_positions: Optional[Dict[Joint, float]] = None,
+        sampling_freq: float = 100,
+        interpolation_mode: InterpolationMode = InterpolationMode.LINEAR,
+    ):
+        """Send joints command to move the robot to a goal_positions within the specified duration.
+
+        This function will block until the movement is over. See goto_async for an asynchronous version.
+
+        The goal positions is expressed in joints coordinates. You can use as many joints target as you want.
+        The duration is expressed in seconds.
+        You can specify the starting_position, otherwise its current position is used,
+        for instance to start from its goal position and avoid bumpy start of move.
+        The sampling freq sets the frequency of intermediate goal positions commands.
+        You can also select an interpolation method use (linear or minimum jerk) which will influence directly the trajectory.
+
+        """
+        def _wrapped_goto(pos):
+            asyncio.run(
+                self.goto_async(
+                    goal_positions=goal_positions,
+                    duration=duration,
+                    starting_positions=starting_positions,
+                    sampling_freq=sampling_freq,
+                    interpolation_mode=interpolation_mode,
+                )
             )
-            setattr(self, name, j)
-            self.joints.append(j)
-
-    def _run_sync_loop_in_bg(self) -> None:
-        from threading import Thread
-
-        t = []
-        t.append(Thread(target=self._get_position_updates))
-        t.append(Thread(target=self._get_temperature_updates))
-        t.append(Thread(target=self._get_load_sensor_updates))
-        # t.append(Thread(target=self._send_commands))
-        t.append(Thread(target=self._stream_commands))
-        t.append(Thread(target=self._get_image))
-
-        for tt in t:
-            tt.daemon = True
-            tt.start()
-
-    def _get_position_updates(self) -> None:
-        req = StreamAllJointsRequest(
-            requested_fields=[JointStateField.PRESENT_POSITION],
-            publish_frequency=self._sync_freq,
-        )
-
-        for update in self._joint_state_stub.StreamAllJointsState(req):
-            for joint, joint_state in zip(self.joints, update.joints):
-                joint._fields['present_position'].value = joint_state.present_position.value
 
-    def _get_temperature_updates(self) -> None:
-        req = StreamAllJointsRequest(
-            requested_fields=[JointStateField.TEMPERATURE],
-            publish_frequency=0.1,
+        with ThreadPoolExecutor() as exec:
+            exec.submit(_wrapped_goto, -20)
+
+    async def goto_async(
+        self,
+        goal_positions: Dict[Joint, float],
+        duration: float,
+        starting_positions: Optional[Dict[Joint, float]] = None,
+        sampling_freq: float = 100,
+        interpolation_mode: InterpolationMode = InterpolationMode.LINEAR,
+    ):
+        """Send joints command to move the robot to a goal_positions within the specified duration.
+
+        This function is asynchronous and will return a Future. This can be used to easily combined multiple gotos.
+        See goto for an blocking version.
+
+        The goal positions is expressed in joints coordinates. You can use as many joints target as you want.
+        The duration is expressed in seconds.
+        You can specify the starting_position, otherwise its current position is used,
+        for instance to start from its goal position and avoid bumpy start of move.
+        The sampling freq sets the frequency of intermediate goal positions commands.
+        You can also select an interpolation method use (linear or minimum jerk) which will influence directly the trajectory.
+
+        """
+        if starting_positions is None:
+            starting_positions = {j: j.present_position for j in goal_positions.keys()}
+
+        length = round(duration * sampling_freq)
+        if length < 1:
+            raise ValueError('Goto length too short! (incoherent duration {duration} or sampling_freq {sampling_freq})!')
+
+        joints = starting_positions.keys()
+        dt = 1 / sampling_freq
+
+        traj_func = interpolation_mode(
+            np.array(list(starting_positions.values())),
+            np.array(list(goal_positions.values())),
+            duration,
         )
-        for update in self._joint_state_stub.StreamAllJointsState(req):
-            for joint, joint_state in zip(self.joints, update.joints):
-                joint._fields['temperature'].value = joint_state.temperature.value
 
-    def _get_load_sensor_updates(self) -> None:
+        t0 = time.time()
         while True:
-            self.left_load_sensor = self._load_sensor_stub.GetLoad(LoadSide(side='left')).load
-            self.right_load_sensor = self._load_sensor_stub.GetLoad(LoadSide(side='right')).load
+            elapsed_time = time.time() - t0
+            if elapsed_time > duration:
+                break
 
-    def _stream_commands(self) -> None:
-        def cmd_gen():
-            while True:
-                commands = self._waiting_commands()
-                if commands:
-                    yield MultipleJointsCommand(commands=commands)
-                time.sleep(1.0 / self._sync_freq)
+            point = traj_func(elapsed_time)
+            for j, pos in zip(joints, point):
+                j.goal_position = pos
 
-        self._joint_command_stub.StreamJointsCommand(cmd_gen())
+            await asyncio.sleep(dt)
 
-    def _send_commands(self) -> None:
-        while True:
-            for cmd in self._waiting_commands():
-                self._joint_command_stub.SendCommand(cmd)
-            time.sleep(1.0 / self._sync_freq)
+    def _setup_joints(self):
+        joint_stub = joint_pb2_grpc.JointServiceStub(self._grpc_channel)
 
-    def _waiting_commands(self) -> List[JointCommand]:
-        return [
-            joint._pop_sync_command()
-            for joint in self.joints if joint._need_sync()
-        ]
+        joint_ids = joint_stub.GetAllJointsId(Empty())
+        self._joint_uid_to_name = dict(zip(joint_ids.uids, joint_ids.names))
+        self._joint_name_to_uid = dict(zip(joint_ids.names, joint_ids.uids))
 
-    def _get_image(self):
-        while True:
-            self.left_image = self._response_to_img(side='left')
-            self.right_image = self._response_to_img(side='right')
-
-    def _response_to_img(self, side):
-        response = self._camera_stub.GetImage(CamSide(side=side))
-        img = np.frombuffer(response.data, dtype=np.uint8)
-        img = cv.imdecode(img, cv.IMREAD_COLOR)
-        return img
-
-    def forward_kinematics(self, arm_side, joints_positions):
-        '''Get from the sdk_server the forward kinematics for a given arm.
-
-        Args:
-            arm_side (str): required arm
-            joints_positions ([float]): list of the present_position of each joints.
-                len(joints_positions) should be equal to 7.
-
-        Returns:
-            :py:class:'~numpy.ndarray': 4x4 homogeneous matrix pose of the end effector
-        '''
-        joints = JointsPosition(positions=joints_positions)
-
-        req = ArmJointsPosition(
-            side=side_to_proto[arm_side],
-            positions=joints
-            )
-        response = self._arm_kinematics_stub.ComputeArmFK(req)
-        return np.array(response.target.data).reshape((4,4))
-
-    def inverse_kinematics(self, arm_side, target, q0):
-        '''Get from the sdk_server the inverse kinematics for a given arm.
-
-        Args:
-            arm_side (str): required arm
-            target (:py:class:`~numpy.ndarray`): 4*4 homogeneous matrix pose for the end effector
-            q0 ([float]): list containing the present_position of each motor joint. 
-                q0 is used to optimize the inverse kinematics computation time.
-
-        Returns:
-            [float]: list containing the goal_position of each motor joint to reach the target
-        '''
-        joints = JointsPosition(positions=q0)
-        target_proto = Matrix4x4(data=np.ndarray.flatten(target))
-
-        req = ArmEndEffector(
-            side=side_to_proto[arm_side],
-            target=target_proto,
-            q0=joints
-            )
-        response = self._arm_kinematics_stub.ComputeArmIK(req)
-        return response.positions.positions
-
-    def zoom_command(self, side, command):
-        '''Send command to Reachy's zoom.
-        
-        Args:
-            side (str): which camera to send the command to. ('right' or 'left')
-            command (str): type of command to send. ('homing', 'in', 'inter' or 'out')
-                'homing': the required zoom camera will perform homing. 
-                    Do it once before changing the zoom level.
-                'in': change zoom to see far objects
-                'out': change zoom to see close objects
-                'inter': zoom level between 'in' and 'out'
-        '''
-        req = ZoomCommand(
-            side=side,
-            command=command
+        req = joint_pb2.JointsStateRequest(
+            ids=[joint_pb2.JointId(uid=uid) for uid in joint_ids.uids],
+            requested_fields=[joint_pb2.JointField.ALL],
         )
-        self._zoom_controller_stub.SendZoomCommand(req)
-
-    def set_zoom_speed(self, speed):
-        '''Change the speed of zoom motors.
-        
-        Args:
-            speed (int): motors speed, must be between 4000 and 40000.
-        '''
-        self._zoom_controller_stub.SetZoomSpeed(ZoomSpeed(speed=speed))
-        
-    def look_at(self, x: float, y: float, z: float, duration: float):
-        '''Perform look_at on Orbita.
-
-        Args:
-            x, y, z (float): coordinates of the point to look_at in the robot frame
-        '''
-        quat = self._orbita_stub.GetQuaternionTransform(
-            Point(
-                x=x,
-                y=y,
-                z=z,
-            )
+        joints_state = joint_stub.GetJointsState(req)
+
+        for joint_id, joint_state in zip(joints_state.ids, joints_state.states):
+            joint = Joint(joint_state)
+
+            self.joints.append(joint)
+            setattr(self, joint.name, joint)
+
+    def _setup_arms(self):
+        try:
+            left_arm = LeftArm(self.joints, self._grpc_channel)
+            setattr(self, 'l_arm', left_arm)
+        except ValueError:
+            pass
+
+        try:
+            right_arm = RightArm(self.joints, self._grpc_channel)
+            setattr(self, 'r_arm', right_arm)
+        except ValueError:
+            pass
+
+    def _setup_fans(self):
+        self._fans_stub = fan_pb2_grpc.FanControllerServiceStub(self._grpc_channel)
+        resp = self._fans_stub.GetAllFansId(Empty())
+        for name, uid in zip(resp.names, resp.uids):
+            fan = Fan(name, uid, stub=self._fans_stub)
+            setattr(self, name, fan)
+            self.fans.append(fan)
+
+    def _setup_force_sensors(self):
+        force_stub = sensor_pb2_grpc.SensorServiceStub(self._grpc_channel)
+        resp = force_stub.GetAllForceSensorsId(Empty())
+        names, uids = resp.names, resp.uids
+
+        resp = force_stub.GetSensorsState(
+            sensor_pb2.SensorsStateRequest(ids=[sensor_pb2.SensorId(uid=uid) for uid in uids]),
         )
-        disks_goals = self._orbita_stub.ComputeOrbitaIK(
-            quat
-        ).sol.positions
-        disks = [self.neck_disk_top, self.neck_disk_middle, self.neck_disk_bottom]
-
-        trajs = np.transpose(
-            np.array(
-                [self._kinematics_stub.ComputeMinjerk(
-                    MinjerkRequest(
-                        present_position=FloatValue(value=np.deg2rad(d.present_position)),
-                        goal_position=FloatValue(value=g),
-                        duration=FloatValue(value=duration)
-                    )
-                ).positions for d,g in zip(disks,disks_goals)]
-            )
+        states = resp.states
+        for name, uid, state in zip(names, uids, states):
+            force_sensor = ForceSensor(name, uid, state.force_sensor_state)
+            setattr(self, name, force_sensor)
+            self.force_sensors.append(force_sensor)
+
+    def _setup_cameras(self):
+        try:
+            channel = grpc.insecure_channel(f'{self._host}:{self._camera_port}')
+            stub = camera_reachy_pb2_grpc.CameraServiceStub(channel)
+            self.left_camera = Camera(side='left', stub=stub)
+            self.right_camera = Camera(side='right', stub=stub)
+
+        except grpc.RpcError:
+            pass
+
+    async def _poll_waiting_commands(self):
+        await asyncio.wait(
+            [asyncio.create_task(joint._need_sync.wait()) for joint in self.joints],
+            return_when=asyncio.FIRST_COMPLETED,
+        )
+        return joint_pb2.JointsCommand(
+            commands=[
+                joint._pop_command()
+                for joint in self.joints if joint._need_sync.is_set()
+            ],
         )
 
-        ids = [18,19,20] # disks id in joint_state publisher list
+    def _start_sync_in_bg(self):
+        loop = asyncio.new_event_loop()
+        loop.run_until_complete(self._sync_loop())
+
+    async def _get_stream_update_loop(self, joint_stub, fields, freq: float):
+        stream_req = joint_pb2.StreamJointsRequest(
+            request=joint_pb2.JointsStateRequest(
+                ids=[joint_pb2.JointId(uid=joint.uid) for joint in self.joints],
+                requested_fields=fields,
+            ),
+            publish_frequency=freq,
+        )
+        async for state_update in joint_stub.StreamJointsState(stream_req):
+            for joint_id, state in zip(state_update.ids, state_update.states):
+                joint = self._get_joint_from_id(joint_id)
+                joint._update_with(state)
+
+    async def _get_stream_sensor_loop(self, async_channel, freq: float):
+        stub = sensor_pb2_grpc.SensorServiceStub(async_channel)
+        stream_req = sensor_pb2.StreamSensorsStateRequest(
+            request=sensor_pb2.SensorsStateRequest(
+                ids=[sensor_pb2.SensorId(uid=sensor.uid) for sensor in self.force_sensors],
+            ),
+            publish_frequency=freq,
+        )
+        async for state_update in stub.StreamSensorStates(stream_req):
+            for sensor_id, state in zip(state_update.ids, state_update.states):
+                sensor = self._get_sensor_from_id(sensor_id)
+                sensor._update_with(state.force_sensor_state)
 
-        for i in range(len(trajs)):
-            cmd =  MultipleJointsCommand(
-                    commands=[
-                        JointCommand(id=id, goal_position=FloatValue(value=trajs[i][id-18]))
-                        for id in ids
-                    ]
-            )
-            self._joint_command_stub.SendAllJointsCommand(cmd)
+    async def _stream_commands_loop(self, joint_stub, freq: float):
+        async def command_poll():
+            last_pub = 0
+            dt = 1.0 / freq
 
+            while True:
+                elapsed_time = time.time() - last_pub
+                if elapsed_time < dt:
+                    await asyncio.sleep(dt - elapsed_time)
+
+                commands = await self._poll_waiting_commands()
+                yield commands
+                last_pub = time.time()
+
+        await joint_stub.StreamJointsCommands(command_poll())
 
-    @property
-    def head_stiff(self):
-        self.neck_disk_top.compliant = False
-        self.neck_disk_middle.compliant = False
-        self.neck_disk_bottom.compliant = False
+    async def _sync_loop(self):
+        for joint in self.joints:
+            joint._setup_sync_loop()
+
+        async_channel = grpc.aio.insecure_channel(f'{self._host}:{self._sdk_port}')
+        joint_stub = joint_pb2_grpc.JointServiceStub(async_channel)
+
+        await asyncio.gather(
+            self._get_stream_update_loop(joint_stub, fields=[joint_pb2.JointField.PRESENT_POSITION], freq=100),
+            self._get_stream_update_loop(joint_stub, fields=[joint_pb2.JointField.TEMPERATURE], freq=0.1),
+            self._get_stream_sensor_loop(async_channel, freq=10),
+            self._stream_commands_loop(joint_stub, freq=100),
+        )
 
-    @property
-    def head_compliant(self):
-        self.neck_disk_top.compliant = True
-        self.neck_disk_middle.compliant = True
-        self.neck_disk_bottom.compliant = True
\ No newline at end of file
+    def _get_joint_from_id(self, joint_id: joint_pb2.JointId) -> Joint:
+        if joint_id.HasField('uid'):
+            return getattr(self, self._joint_uid_to_name[joint_id.uid])
+        else:
+            return getattr(self, joint_id.name)
+
+    def _get_sensor_from_id(self, sensor_id: sensor_pb2.SensorId) -> ForceSensor:
+        if sensor_id.HasField('uid'):
+            for sensor in self.force_sensors:
+                if sensor.uid == sensor_id.uid:
+                    return sensor
+            raise IndexError
+        else:
+            return getattr(self, sensor_id.name)
diff --git a/reachy_sdk/register.py b/reachy_sdk/register.py
new file mode 100644
index 0000000..a6d482a
--- /dev/null
+++ b/reachy_sdk/register.py
@@ -0,0 +1,107 @@
+"""
+Define a Register class and meta-class to handle in background.
+
+Handles:
+- whether a register is RO or RW
+- the conversion from internal representation (usually a google protobuf value) to the external one (base Python type)
+- store of the actual value in the associated instance of the meta-class (Joint in our case).
+
+"""
+from typing import Any, Callable, Optional, Tuple, Type
+
+from google.protobuf.wrappers_pb2 import BoolValue, FloatValue, UInt32Value
+
+from reachy_sdk_api.joint_pb2 import ComplianceMarginSlope, PIDGains
+
+
+class Register:
+    """Register class to expose the stored value in a more simple way.
+
+    The internal representation is directly the gRPC object deserialized.
+    As this is not convenient to work with, we convert it to base python type (int, tuple, float, etc).
+
+    The register also checks the access right (RO or RW).
+
+    The synchronisation with the gRPC messages is actually done by the Joint.
+    """
+
+    label: str = ''
+
+    def __init__(self,
+                 readonly: bool,
+                 type: Type[Any],
+                 conversion: Optional[Tuple[Callable[[Any], Any], Callable[[Any], Any]]] = None,
+                 ) -> None:
+        """Set up the register."""
+        self.readonly = readonly
+        self.internal_class = type
+
+        self.cvt_to_internal: Optional[Callable[[Any], Any]] = None
+        self.cvt_to_external: Optional[Callable[[Any], Any]] = None
+        if conversion is not None:
+            self.cvt_to_internal, self.cvt_to_external = conversion
+
+    def __get__(self, instance, owner):
+        """Unwrap, optionally convert the internal value and return it."""
+        value = self.unwrapped_value(instance[self.label])
+        if self.cvt_to_external is not None:
+            value = self.cvt_to_external(value)
+        return value
+
+    def __set__(self, instance, value):
+        """Convert (if needed) the given value, wrap it and store it internally."""
+        if self.readonly:
+            raise AttributeError("can't set attribute")
+
+        if self.cvt_to_internal is not None:
+            value = self.cvt_to_internal(value)
+
+        instance[self.label] = self.wrapped_value(value)
+
+    def unwrapped_value(self, value: Any) -> Any:
+        """Unwrap the internal value to a more simple one."""
+        if self.internal_class in (BoolValue, FloatValue, UInt32Value):
+            return value.value
+
+        # Circumvent https://github.com/grpc/grpc/issues/18139
+        if self.internal_class.__name__ == 'PIDValue':
+            if value.HasField('pid'):
+                return (value.pid.p, value.pid.i, value.pid.d)
+            elif value.HasField('compliance'):
+                return (
+                    value.compliance.cw_compliance_margin, value.compliance.ccw_compliance_margin,
+                    value.compliance.cw_compliance_slope, value.compliance.ccw_compliance_slope,
+                )
+            else:
+                raise ValueError('Empty PIDValue received!')
+
+        return value
+
+    def wrapped_value(self, value: Any) -> Any:
+        """Wrap the simple Python value to the corresponding gRPC one."""
+        if self.internal_class in (BoolValue, FloatValue, UInt32Value):
+            return self.internal_class(value=value)
+
+        elif self.internal_class.__name__ == 'PIDValue':
+            if len(value) == 3:
+                return self.internal_class(pid=PIDGains(p=value[0], i=value[1], d=value[2]))
+            elif len(value) == 4:
+                return self.internal_class(compliance=ComplianceMarginSlope(
+                    cw_compliance_margin=value[0], ccw_compliance_margin=value[1],
+                    cw_compliance_slope=value[2], ccw_compliance_slope=value[3],
+                ))
+            else:
+                raise ValueError('Empty PIDValue received!')
+
+        return value
+
+
+class MetaRegister(type):
+    """MetaClass used to facilitate the registration of the Register in the Joint."""
+
+    def __new__(cls, name, bases, attrs):
+        """Register the label of the register as it is used by the Joint to store its value using it as key."""
+        for field, value in attrs.items():
+            if isinstance(value, Register):
+                value.label = field
+        return super().__new__(cls, name, bases, attrs)
diff --git a/reachy_sdk/trajectory/__init__.py b/reachy_sdk/trajectory/__init__.py
new file mode 100644
index 0000000..00256a5
--- /dev/null
+++ b/reachy_sdk/trajectory/__init__.py
@@ -0,0 +1,1 @@
+"""Trajectory utility package."""
diff --git a/reachy_sdk/trajectory/interpolation.py b/reachy_sdk/trajectory/interpolation.py
new file mode 100644
index 0000000..78fab7a
--- /dev/null
+++ b/reachy_sdk/trajectory/interpolation.py
@@ -0,0 +1,80 @@
+"""Trajectory interpolation utility module.
+
+Provides two main interpolation methods:
+- linear
+- minimum jerk
+"""
+
+from enum import Enum
+from typing import Callable, Optional
+
+import numpy as np
+
+
+InterpolationFunc = Callable[[float], np.ndarray]
+
+
+def linear(
+    starting_position: np.ndarray,
+    goal_position: np.ndarray,
+    duration: float,
+) -> InterpolationFunc:
+    """Compute the linear interpolation function from starting position to goal position."""
+    def f(t: float) -> np.ndarray:
+        return starting_position + (goal_position - starting_position) * t / duration
+    return f
+
+
+def minimum_jerk(
+    starting_position: np.ndarray,
+    goal_position: np.ndarray,
+    duration: float,
+    starting_velocity: Optional[np.ndarray] = None,
+    starting_acceleration: Optional[np.ndarray] = None,
+    final_velocity: Optional[np.ndarray] = None,
+    final_acceleration: Optional[np.ndarray] = None,
+) -> InterpolationFunc:
+    """Compute the mimimum jerk interpolation function from starting position to goal position."""
+    if starting_velocity is None:
+        starting_velocity = np.zeros(starting_position.shape)
+    if starting_acceleration is None:
+        starting_acceleration = np.zeros(starting_position.shape)
+    if final_velocity is None:
+        final_velocity = np.zeros(goal_position.shape)
+    if final_acceleration is None:
+        final_acceleration = np.zeros(goal_position.shape)
+
+    a0 = starting_position
+    a1 = starting_velocity
+    a2 = starting_acceleration / 2
+
+    d1, d2, d3, d4, d5 = [duration ** i for i in range(1, 6)]
+
+    A = np.array((
+        (d3, d4, d5),
+        (3 * d2, 4 * d3, 5 * d4),
+        (6 * d1, 12 * d2, 20 * d3)
+    ))
+    B = np.array((
+        goal_position - a0 - (a1 * d1) - (a2 * d2),
+        final_velocity - a1 - (2 * a2 * d1),
+        final_acceleration - (2 * a2)
+    ))
+    X = np.linalg.solve(A, B)
+
+    coeffs = [a0, a1, a2, X[0], X[1], X[2]]
+
+    def f(t: float) -> np.ndarray:
+        return np.sum([
+            c * t ** i
+            for i, c in enumerate(coeffs)
+        ], axis=0)
+
+    return f
+
+
+class InterpolationMode(Enum):
+    """Inteprolation Mode enumeration."""
+
+    LINEAR: Callable[[np.ndarray, np.ndarray, float], InterpolationFunc] = linear
+    MINIMUM_JERK: Callable[[np.ndarray, np.ndarray, float], InterpolationFunc] = minimum_jerk
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000..6f0d7f9
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,3 @@
+[flake8]
+exclude = test
+max-line-length = 128
\ No newline at end of file
diff --git a/setup.py b/setup.py
index 0ddb3b0..6a80b3a 100644
--- a/setup.py
+++ b/setup.py
@@ -1,4 +1,5 @@
 #!/usr/bin/env python
+"""Setup config file."""
 
 from os import path
 
@@ -17,6 +18,8 @@
     packages=find_packages(exclude=['tests']),
 
     install_requires=[
+        'numpy',
+        'opencv-python',
         'reachy-sdk-api',
         'grpcio',
         'protobuf>3',
@@ -29,4 +32,4 @@
     description='Python Reachy SDK.',
     long_description=long_description,
     long_description_content_type='text/markdown',
-)
\ No newline at end of file
+)


Test patch:
diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml
new file mode 100644
index 0000000..e955acf
--- /dev/null
+++ b/.github/workflows/pytest.yml
@@ -0,0 +1,17 @@
+name: Run pytest.
+on: [push]
+
+jobs:
+  pytest:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v2
+    - uses: actions/setup-python@v2
+      with:
+        python-version: '3.8'
+
+    - name: Pytest
+      run: |
+        pip install pytest
+        pip install -e .
+        python -m pytest .
\ No newline at end of file
diff --git a/test/test_import.py b/test/test_import.py
new file mode 100644
index 0000000..0b5ac34
--- /dev/null
+++ b/test/test_import.py
@@ -0,0 +1,5 @@
+def test_module_import():
+    import reachy_sdk
+
+def test_reachy_import():
+    from reachy_sdk import ReachySDK
\ No newline at end of file