Skip to content

Commit

Permalink
Merge branch 'master' into key-control
Browse files Browse the repository at this point in the history
  • Loading branch information
WT-MM authored Oct 16, 2024
2 parents 2e0d00d + b41ea3e commit 81fcab6
Show file tree
Hide file tree
Showing 14 changed files with 1,445 additions and 758 deletions.
41 changes: 4 additions & 37 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,47 +1,14 @@
# Makefile

define HELP_MESSAGE
actuator

# Installing

1. Create a new Conda environment: `conda create --name actuator python=3.11`
2. Activate the environment: `conda activate actuator`
3. Install the package: `make install-dev`

# Running Tests

1. Run autoformatting: `make format`
2. Run static checks: `make static-checks`
3. Run unit tests: `make test`

endef
export HELP_MESSAGE

all:
@echo "$$HELP_MESSAGE"
.PHONY: all

# ------------------------ #
# Build #
# ------------------------ #

install-and-run:
install:
cargo run --bin stub_gen
@touch setup.py
@uv pip install -e '.[dev]'
@python -m actuator.cli
.PHONY: install-and-run

build-rust:
@RUST_BACKTRACE=1 cargo build -p lib
.PHONY: build-rust

build-stubs:
@RUST_BACKTRACE=1 cargo run --bin stub_gen -p lib --verbose
.PHONY: build-stubs

clean:
rm -rf build dist *.so **/*.so **/*.pyi **/*.pyc **/*.pyd **/*.pyo **/__pycache__ *.egg-info .eggs/ .ruff_cache/
.PHONY: clean
.PHONY: build

# ------------------------ #
# Static Checks #
Expand Down
64 changes: 2 additions & 62 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,68 +2,8 @@

Defines a package to make it easy and performant to control actuators.

![System Architecture](https://github.com/user-attachments/assets/b10f82df-854f-4252-ba4e-e1f77419767a)
![System Architecture](./docs/architecture.png)

## Getting Started

### Install Build Dependencies

#### Ubuntu

```bash
sudo apt install pkg-config libudev-dev
```

### Install the Package

```bash
pip install actuator
```

Alternatively, to install the bleeding edge version from Github:

```bash
pip install 'actuator @ git+https://github.com/kscalelabs/actuator.git@master'
```

### Motor-Specific Examples

#### Robstride

The following example can be used to move a Robstride motor in a sinusoidal pattern.

```bash
python -m actuator.examples.sinusoidal_movement
```

Note that there are some additional steps needed before the Robstride USB controller will work on Linux:

1. Install [this driver](https://github.com/WCHSoftGroup/ch341ser_linux) for the CH341 USB controller.
2. This should create a `/dev/ttyUSB0` or `/dev/ttyCH341USB0` device - you should check which one by doing `ls /dev/tty*`.
You might need to the change the permissions:

```bash
sudo chmod 666 /dev/ttyCH341USB0
```

3. Run the following command to configure the baud rate of the controller:

```bash
sudo stty -F /dev/ttyUSB0 921600
```

4. Alternatively, you can add the following line to your `/etc/udev/rules.d/51-ch340.rules` file to automatically configure the baud rate:
```bash
KERNEL=="ttyCH341USB[0-9]", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", SYMLINK+="ttyUSB%n", RUN+="/bin/stty -F /dev/ttyCH341USB0 921600"
KERNEL=="ttyUSB[0-9]", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", RUN+="/bin/stty -F /dev/ttyUSB0 921600"
```

5. After adding the above rule, you should run `sudo udevadm control --reload-rules` to reload the rules.


## Supported Actuators

- [Robstride](https://robstride.com/)

ATTRS{idVendor}=="1a86"
ATTRS{idProduct}=="7523"
See the documentation [here](https://docs.kscale.dev/software/actuators/overview) for instructions on getting started with this package.
5 changes: 4 additions & 1 deletion actuator/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
__version__ = "0.0.10"
"""Defines the top-level API for the actuator package."""

__version__ = "0.0.19"

from .rust.bindings import (
PyRobstrideMotorControlParams as RobstrideMotorControlParams,
PyRobstrideMotorFeedback as RobstrideMotorFeedback,
PyRobstrideMotors as RobstrideMotors,
PyRobstrideMotorsSupervisor as RobstrideMotorsSupervisor,
Expand Down
76 changes: 63 additions & 13 deletions actuator/rust/bindings/bindings.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@

import typing

class PyRobstrideMotorControlParams:
position: float
velocity: float
kp: float
kd: float
torque: float
def __new__(cls,position:float, velocity:float, kp:float, kd:float, torque:float): ...
def __repr__(self) -> str:
...


class PyRobstrideMotorFeedback:
can_id: int
position: float
Expand All @@ -15,41 +26,59 @@ class PyRobstrideMotorFeedback:


class PyRobstrideMotors:
def __new__(cls,port_name:str, motor_infos:typing.Mapping[int, str]): ...
def __new__(cls,port_name,motor_infos,verbose = ...): ...
def send_get_mode(self) -> dict[int, str]:
...

def send_set_zero(self, motor_ids:typing.Optional[typing.Sequence[int]]) -> dict[int, PyRobstrideMotorFeedback]:
def send_set_zero(self, motor_ids:typing.Optional[typing.Sequence[int]]) -> None:
...

def send_reset(self) -> dict[int, PyRobstrideMotorFeedback]:
def send_resets(self) -> None:
...

def send_start(self) -> dict[int, PyRobstrideMotorFeedback]:
def send_starts(self) -> None:
...

def send_torque_controls(self, torque_sets:typing.Mapping[int, float]) -> dict[int, PyRobstrideMotorFeedback]:
def send_motor_controls(self, motor_controls:typing.Mapping[int, PyRobstrideMotorControlParams], serial:bool) -> dict[int, PyRobstrideMotorFeedback]:
...

def get_latest_feedback(self) -> dict[int, PyRobstrideMotorFeedback]:
def __repr__(self) -> str:
...

def get_latest_feedback_for(self, motor_id:int) -> PyRobstrideMotorFeedback:

class PyRobstrideMotorsSupervisor:
total_commands: int
actual_update_rate: float
serial: bool
def __new__(cls,port_name,motor_infos,verbose = ...,target_update_rate = ...,can_timeout = ...): ...
def set_position(self, motor_id:int, position:float) -> float:
...

def __repr__(self) -> str:
def get_position(self, motor_id:int) -> float:
...

def set_velocity(self, motor_id:int, velocity:float) -> float:
...

class PyRobstrideMotorsSupervisor:
def __new__(cls,port_name:str, motor_infos:typing.Mapping[int, str]): ...
def set_target_position(self, motor_id:int, position:float) -> None:
def get_velocity(self, motor_id:int) -> float:
...

def set_kp(self, motor_id:int, kp:float) -> float:
...

def get_kp(self, motor_id:int) -> float:
...

def set_kp_kd(self, motor_id:int, kp:float, kd:float) -> None:
def set_kd(self, motor_id:int, kd:float) -> float:
...

def set_sleep_duration(self, sleep_duration:float) -> None:
def get_kd(self, motor_id:int) -> float:
...

def set_torque(self, motor_id:int, torque:float) -> float:
...

def get_torque(self, motor_id:int) -> float:
...

def add_motor_to_zero(self, motor_id:int) -> None:
Expand All @@ -58,10 +87,31 @@ class PyRobstrideMotorsSupervisor:
def get_latest_feedback(self) -> dict[int, PyRobstrideMotorFeedback]:
...

def toggle_pause(self) -> None:
...

def stop(self) -> None:
...

def __repr__(self) -> str:
...

def set_params(self, motor_id:int, params:PyRobstrideMotorControlParams) -> None:
...

def failed_commands_for(self, motor_id:int) -> int:
...

def reset_command_counters(self) -> None:
...

def is_running(self) -> bool:
...

def max_update_rate(self, rate:float) -> None:
...

def toggle_serial(self) -> bool:
...


Loading

0 comments on commit 81fcab6

Please sign in to comment.