Skip to content

Commit

Permalink
Merge branch 'develop' into 106-improve-code-documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
simheo committed Nov 10, 2023
2 parents 696ef1a + ba3cc9e commit 9d4a6e2
Show file tree
Hide file tree
Showing 17 changed files with 311 additions and 141 deletions.
26 changes: 21 additions & 5 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,32 @@ on: [push]
jobs:

black:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: psf/black@stable
with:
options: "--check --verbose --line-length 128"
options: "--check --verbose"
version: "23.3.0"

isort:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.10
uses: actions/setup-python@v4
with:
python-version: "3.10"
cache: 'pip' # caching pip dependencies
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install .[dev]
- name : Check import order
run : isort . -c

flake8:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.10
Expand All @@ -31,10 +47,10 @@ jobs:
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# option --exit-zero can be added to this line to set these errors as warnings
flake8 . --count --max-complexity=10 --max-line-length=128 --statistics
flake8 . --count --statistics --config setup.cfg
mypy:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.10
Expand Down
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
# Python SDK for Reachy v2
# Python SDK for Reachy v2

## Install

```console
$ pip install -e .[pollen,dev]
```

*[dev]* contains the tools for developers.
*[pollen]* has the custom pollen robotics repos. It is mandatory but not in the default install because github actions cannot fetch private repo directly.
57 changes: 0 additions & 57 deletions docs/convention_maths.md

This file was deleted.

8 changes: 7 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"
build-backend = "setuptools.build_meta"

[tool.isort]
profile = "black"

[tool.black]
line-length = 128
7 changes: 5 additions & 2 deletions scripts/git_hooks/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,17 @@
set -eo pipefail

# Run black against all code in the `source_code` directory
black . --line-length 128 --check
black . --check
echo "-------> Black passed!"

# Run isort against all code in the `source_code` directory
isort . -c
echo "-------> Isort passed!"

# Run flake8 against all code in the `source_code` directory
flake8 .
echo "-------> Flake8 passed!"

# Run mypy against all code in the `source_code` directory
mypy .
echo "-------> Mypy passed!"

32 changes: 15 additions & 17 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,37 +1,35 @@
[metadata]
name = reachy-v2-sdk
version = 0.1.0
version = 2.0
author = Pollen Robotics
author_email = [email protected]
url = https://github.com/pollen-robotics/python-template
description = Python template project
url = https://github.com/pollen-robotics/reachy-v2-sdk
description = Reachy SDK V2
long_description = file: README.md
long_description_content_type = text/markdown


[options]
packages = find:
packages = reachy_v2_sdk
zip_safe = True
include_package_data = True
package_dir=
=src
install_requires =
numpy
numpy==1.26.1
protobuf==4.25.0
grpcio==1.59.2
pyquaternion==0.9.9

[options.packages.find]
where=reachy_sdk

[options.extras_require]
dev = black==23.3.0
flake8==6.0.0
pytest==7.3.1
coverage==7.2.5
mypy==1.0.0
dev = black==23.10.1
flake8==6.1.0
pytest==7.4.3
coverage==7.3.2
mypy==1.6.1
isort==5.12.0
types-protobuf==4.24.0.1

[options.entry_points]
console_scripts =
example_entry_point = example.celcius:main
pollen = reachy-sdk-api-v2@git+ssh://[email protected]/pollen-robotics/reachy-sdk-api-v2.git#subdirectory=python

[flake8]
exclude = tests
Expand Down
Empty file removed src/example/__init__.py
Empty file.
19 changes: 15 additions & 4 deletions src/reachy_v2_sdk/arm.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,10 @@ def forward_kinematics(
return np.array(resp.end_effector.pose.data).reshape((4, 4))

def inverse_kinematics(
self, target: npt.NDArray[np.float64], q0: Optional[List[float]] = None, degrees: bool = True
self,
target: npt.NDArray[np.float64],
q0: Optional[List[float]] = None,
degrees: bool = True,
) -> List[float]:
"""Compute the inverse kinematics of the arm.
Expand Down Expand Up @@ -182,8 +185,14 @@ def _list_to_arm_position(self, positions: List[float], degrees: bool = True) ->
if degrees:
positions = self._convert_to_radians(positions)
arm_pos = ArmPosition(
shoulder_position=Pose2D(axis_1=FloatValue(value=positions[0]), axis_2=FloatValue(value=positions[1])),
elbow_position=Pose2D(axis_1=FloatValue(value=positions[2]), axis_2=FloatValue(value=positions[3])),
shoulder_position=Pose2D(
axis_1=FloatValue(value=positions[0]),
axis_2=FloatValue(value=positions[1]),
),
elbow_position=Pose2D(
axis_1=FloatValue(value=positions[2]),
axis_2=FloatValue(value=positions[3]),
),
wrist_position=Rotation3D(
rpy=ExtEulerAngles(
roll=positions[4],
Expand Down Expand Up @@ -277,7 +286,9 @@ def goto(
)
if orientation_tol is not None:
target.orientation_tolerance = ExtEulerAnglesTolerances(
x_tol=orientation_tol[0], y_tol=orientation_tol[1], z_tol=orientation_tol[2]
x_tol=orientation_tol[0],
y_tol=orientation_tol[1],
z_tol=orientation_tol[2],
)
self._arm_stub.GoToCartesianPosition(target)

Expand Down
70 changes: 70 additions & 0 deletions src/reachy_v2_sdk/audio.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"""Reachy Audio module.
Handles all specific method related to audio especially:
- playing sounds
- recording sounds
"""
from typing import List

import grpc
from google.protobuf.empty_pb2 import Empty
from reachy_sdk_api_v2.sound_pb2 import (
RecordingRequest,
SoundId,
SoundRequest,
VolumeRequest,
)
from reachy_sdk_api_v2.sound_pb2_grpc import SoundServiceStub


class Audio:
"""Audio class used for microphone and speakers.
It exposes functions to:
- play / stop sounds with defined speakers,
- test the speakers,
- record tracks with a defined microphone,
"""

def __init__(self, host: str, port: int) -> None:
"""Set up audio module, along with microphone and speakers."""
self._grpc_audio_channel = grpc.insecure_channel(f"{host}:{port}")

self._audio_stub = SoundServiceStub(self._grpc_audio_channel)
self._setup_microphones()
self._setup_speakers()

def _setup_microphones(self) -> None:
micro_info = self._audio_stub.GetAllMicrophone(Empty())
self._microphone_id = micro_info.microphone_info[0].id

def _setup_speakers(self) -> None:
speaker_info = self._audio_stub.GetAllSpeaker(Empty())
self._speaker_id = speaker_info.speaker_info[0].id

def testing(self) -> None:
self._audio_stub.TestSpeaker(self._speaker_id)

def get_sounds_list(self) -> List[str]:
sounds = self._audio_stub.GetSoundsList(Empty())
return [soundId.id for soundId in sounds.sounds]

def play(self, sound_name: str, volume: float = 0.5) -> None:
available_sounds = self.get_sounds_list()
if sound_name not in available_sounds:
raise ValueError(f"Sound to play not available! Sounds available are {available_sounds}")
if not 0 <= volume <= 1:
raise ValueError(f"Volume should be between 0 and 1, got {volume}")
self._audio_stub.PlaySound(SoundRequest(speaker=self._speaker_id, sound=SoundId(id=sound_name, volume=volume)))

def stop(self) -> None:
self._audio_stub.StopSound(ComponentId=self._speaker_id)

def start_recording(self, sound_name: str) -> None:
self._audio_stub.StartRecording(RecordingRequest(micro=self._microphone_id, recording_id=SoundId(id=sound_name)))

def stop_recording(self) -> None:
self._audio_stub.StopRecording(self._microphone_id)

def set_audio_volume(self, volume: int) -> None:
self._audio_stub.ChangeVolume(VolumeRequest(id=self._speaker_id, volume=volume))
8 changes: 7 additions & 1 deletion src/reachy_v2_sdk/dynamixel_motor.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,13 @@ class DynamixelMotor:
speed_limit = Register(readonly=False, type=FloatValue, label="speed_limit")
torque_limit = Register(readonly=False, type=FloatValue, label="torque_limit")

def __init__(self, uid: int, name: str, initial_state: DynamixelMotorState, grpc_channel: Channel):
def __init__(
self,
uid: int,
name: str,
initial_state: DynamixelMotorState,
grpc_channel: Channel,
):
self.id = uid
self.name = name
self._stub = DynamixelMotorServiceStub(grpc_channel)
Expand Down
10 changes: 8 additions & 2 deletions src/reachy_v2_sdk/head.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,9 @@ def forward_kinematics(self, rpy_position: Optional[Tuple[float, float, float]]
return pyQuat(w=quat.w, x=quat.x, y=quat.y, z=quat.z)

def inverse_kinematics(
self, orientation: Optional[pyQuat] = None, rpy_q0: Optional[Tuple[float, float, float]] = None
self,
orientation: Optional[pyQuat] = None,
rpy_q0: Optional[Tuple[float, float, float]] = None,
) -> Tuple[float, float, float]:
"""Compute the inverse kinematics of the arm.
Expand All @@ -137,7 +139,11 @@ def inverse_kinematics(
req_params["q0"] = Rotation3D(rpy=ExtEulerAngles(roll=rpy_q0[0], pitch=rpy_q0[1], yaw=rpy_q0[2]))
req = NeckIKRequest(**req_params)
rpy_pos = self._head_stub.ComputeNeckIK(req)
return (rpy_pos.position.rpy.roll, rpy_pos.position.rpy.pitch, rpy_pos.position.rpy.yaw)
return (
rpy_pos.position.rpy.roll,
rpy_pos.position.rpy.pitch,
rpy_pos.position.rpy.yaw,
)

def look_at(self, x: float, y: float, z: float, duration: float) -> None:
"""Compute and send neck rpy position to look at the (x, y, z) point in Reachy cartesian space (torso frame).
Expand Down
5 changes: 4 additions & 1 deletion src/reachy_v2_sdk/orbita2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,10 @@ def __init__( # noqa: C901
axis2_name,
OrbitaJoint2D(initial_state=init_state["axis_2"], axis_type=axis2_name, actuator=self),
)
self._joints = {"axis_1": getattr(self, axis1_name), "axis_2": getattr(self, axis2_name)}
self._joints = {
"axis_1": getattr(self, axis1_name),
"axis_2": getattr(self, axis2_name),
}

self.__motor_1 = OrbitaMotor(initial_state=init_state["motor_1"], actuator=self)
self.__motor_2 = OrbitaMotor(initial_state=init_state["motor_2"], actuator=self)
Expand Down
Loading

0 comments on commit 9d4a6e2

Please sign in to comment.