CAN-FD driver and Python bindings for the Leadshine DH116 6-DOF dexterous robot hand.
| Dependency | Purpose |
|---|---|
| C++17 compiler | Build |
| CMake >= 3.16 | Build |
| spdlog | Logging |
| yaml-cpp | Config parsing |
| pybind11 | Python bindings |
| LHandProLib | DH116 protocol library (bundled) |
sudo apt install cmake python3-dev pybind11-dev libspdlog-dev libyaml-cpp-dev
cmake -B build -DCMAKE_INSTALL_PREFIX=/opt/roboparty -DCMAKE_BUILD_TYPE=Release
cmake --build build
sudo cmake --install builddpkg-buildpackage -b -us -uc
sudo dpkg -i ../roboparty-hand_*.debCreate /etc/udev/rules.d/99-canfd.rules before connecting:
ACTION=="add", SUBSYSTEM=="net", KERNEL=="can*", RUN+="/sbin/ip link set $name type can bitrate 1000000 dbitrate 5000000 fd on", RUN+="/sbin/ip link set $name up"
Then reload:
sudo udevadm control --reload-rules && sudo udevadm triggerconfig/hand.yaml maps hand names to CAN interfaces:
left_hand:
can_interface: can0
type: LRO
protocol: canfd
right_hand:
can_interface: can1
type: LRO
protocol: canfdInstalled to /opt/roboparty/share/roboparty_hand/config/.
import hand_py
import time
left = hand_py.HandDriver()
left.connect_by_config("config/hand.yaml", "left_hand")
dof = left.get_active_dof()
for j in range(dof):
left.set_enable(j, 1)
left.set_positions([500.0, 500.0, 500.0, 500.0, 500.0, 500.0])
time.sleep(0.1)
angles = left.get_now_angles(dof)
print(angles)
left.disconnect()| Method | Description |
|---|---|
connect(device_index=0) |
Connect by CAN interface index |
connect_by_config(path, name) |
Connect by YAML config and hand name |
disconnect() |
Close the connection |
is_connected() |
Check connection status |
get_active_dof() |
Number of active DOF |
set_enable(joint_id, enable) |
Enable/disable a motor (0/1) |
set_position(joint_id, pos) |
Set target position |
get_position(joint_id) |
Get target position |
get_now_position(joint_id) |
Get current position |
get_now_angle(joint_id) |
Get current angle (degrees) |
get_now_position_velocity(joint_id) |
Get current velocity |
get_now_current(joint_id) |
Get current draw (mA) |
set_position_velocity(joint_id, vel) |
Set velocity limit |
get_position_velocity(joint_id) |
Get velocity limit |
get_max_current(joint_id) |
Get max current (mA) |
set_max_current(joint_id, cur) |
Set max current (mA) |
get_control_mode(joint_id) |
Get control mode |
set_control_mode(joint_id, mode) |
Set control mode |
home_motors(joint_id) |
Home motor |
move_motors(joint_id) |
Move motor after homing |
get_now_alarm(joint_id) |
Get alarm status |
Batch methods (inference-friendly):
| Method | Description |
|---|---|
set_positions(positions) |
Batch set target positions |
get_now_angles(count) |
Batch read angles → list[float] |
get_now_positions(count) |
Batch read positions → list[int] |
#include "hand_driver.hpp"
hand::HandDriver driver;
driver.connect("config/hand.yaml", "left_hand");
driver.setEnable(0, 1);
driver.setPosition(0, 1000);
float angles[6];
driver.getNowAngles(angles, 6);Link with CMake:
find_package(roboparty_hand REQUIRED)
target_link_libraries(my_app roboparty_hand::handcontroller)GPL-3.0 — see LICENSE.