# Vassar Feetech Servo SDK
A comprehensive Python SDK and command-line tool for controlling Feetech servos (STS/HLS series).
## Features
- 🔌 **Auto-detection** of serial ports
- 🎯 **Support for STS and HLS servos** (HLS includes torque control)
- 📖 **Read positions** from single or multiple servos
- 🎯 **Set middle position** - Calibrate servos to position 2048
- ✍️ **Write position targets** (coming soon)
- 💪 **Write torque targets** (coming soon)
- 🚀 **High-performance** group sync operations
- 📊 **Real-time monitoring** with configurable update rates
- 🐍 **Clean Python API** with servo configuration at initialization
- 💻 **Command-line interface** for all operations
- 🔧 **Context manager support** for clean resource management
## Installation
### From PyPI
```bash
pip install vassar-feetech-servo-sdk
```
### From Source
```bash
git clone https://github.com/vassar-robotics/feetech-servo-sdk.git
cd feetech-servo-sdk
pip install -e .
```
## Dependencies
- Python >= 3.7
- pyserial >= 3.5
Note: The `scservo_sdk` is bundled with this package, so no separate installation is needed.
## Quick Start
### Command Line Usage
```bash
# Read from motors 1-6 continuously at 30Hz
vassar-servo
# Set all servos to middle position
vassar-servo --set-middle
# Read from specific motors at 60Hz
vassar-servo --motor-ids 1,3,5 --hz 60
# Use HLS servos (default is STS)
vassar-servo --servo-type hls
# Read once and exit
vassar-servo --once
# Output JSON format (useful for scripting)
vassar-servo --once --json
```
### Python API Usage
```python
from vassar_feetech_servo_sdk import ServoController
# Initialize controller with your servo configuration
servo_ids = [1, 2, 3, 4, 5, 6]
controller = ServoController(servo_ids=servo_ids, servo_type="sts") # or "hls"
controller.connect()
# Read all configured servos
positions = controller.read_all_positions()
for motor_id, pos in positions.items():
print(f"Motor {motor_id}: {pos} ({pos/4095*100:.1f}%)")
# Set servos to middle position
success = controller.set_middle_position()
if success:
print("All servos calibrated to middle position!")
controller.disconnect()
# Using context manager
with ServoController([1, 2, 3], "sts") as controller:
positions = controller.read_all_positions()
print(positions)
```
### Changing Servo IDs
```python
from vassar_feetech_servo_sdk import ServoController
# Connect to a servo with current ID 1
controller = ServoController(servo_ids=[1], servo_type="sts")
controller.connect()
# Change its ID from 1 to 10
success = controller.set_motor_id(
current_id=1,
new_id=10,
confirm=True # Will ask for user confirmation
)
if success:
print("ID changed! Power cycle the servo to apply.")
controller.disconnect()
# After power cycling, connect with new ID
controller = ServoController(servo_ids=[10], servo_type="sts")
controller.connect()
```
### Advanced Usage
```python
# Initialize with specific configuration
controller = ServoController(
servo_ids=[1, 2, 3, 4, 5, 6],
servo_type="hls", # 'sts' or 'hls'
port="/dev/ttyUSB0",
baudrate=1000000
)
# Error handling
from vassar_feetech_servo_sdk import ServoReaderError, PortNotFoundError
try:
controller = ServoController([1, 2, 3], "sts")
controller.connect()
positions = controller.read_all_positions()
except PortNotFoundError:
print("No servo port found!")
except ServoReaderError as e:
print(f"Error: {e}")
```
## API Reference
### ServoController Class
#### Constructor
```python
ServoController(servo_ids, servo_type="sts", port=None, baudrate=1000000)
```
- `servo_ids`: List of servo IDs to control (e.g., [1, 2, 3, 4, 5, 6])
- `servo_type`: Type of servo - 'sts' or 'hls' (default: 'sts')
- `port`: Serial port path (auto-detect if None)
- `baudrate`: Communication speed (default: 1000000)
#### Methods
- `connect()`: Establish connection to servos
- `disconnect()`: Close connection
- `read_position(motor_id)`: Read single motor position
- `read_positions(motor_ids=None)`: Read multiple motor positions
- `read_all_positions()`: Read all configured servo positions
- `set_middle_position(motor_ids=None)`: Calibrate servos to middle position (2048)
- `set_motor_id(current_id, new_id, confirm=True)`: Change a servo's ID (requires power cycle)
### Utility Functions
- `find_servo_port()`: Auto-detect servo serial port
## Servo Types
- **STS**: Standard Feetech servos (default) - position and speed control
- Middle position calibration uses torque=128 method
- **HLS**: High-end servos with additional torque control capabilities
- Middle position calibration uses offset calibration (`reOfsCal`) method
## Troubleshooting
### Port Not Found
If auto-detection fails, specify the port manually:
```bash
# Linux
vassar-servo --port /dev/ttyUSB0
# macOS
vassar-servo --port /dev/tty.usbserial-*
# Windows
vassar-servo --port COM3
```
### Permission Denied (Linux)
Option 1: Add your user to the dialout group (recommended):
```bash
sudo usermod -a -G dialout $USER
# Log out and back in for changes to take effect
```
Option 2: Grant permissions to the serial port (temporary):
```bash
sudo chmod 666 /dev/ttyUSB0
# Replace /dev/ttyUSB0 with your actual serial port
```
### Connection Failed
1. Check servo power supply
2. Verify baudrate matches servo configuration (default: 1000000)
3. Ensure proper wiring (TX/RX not swapped)
## Examples
The package includes several example scripts in the `examples/` directory:
- `basic_usage.py` - Simple example showing how to connect and read servo positions
- `continuous_reading.py` - Real-time monitoring with custom callbacks
- `servo_types.py` - Demonstrates differences between STS and HLS servos
- `set_middle_position.py` - Shows how to calibrate servos to middle position
## Testing
Run the test suite:
```bash
./run_tests.sh # Installs dev dependencies and runs tests with coverage
# or
pip install -r requirements-dev.txt
python -m pytest tests/ -v
```
## Acknowledgments
Built on top of the excellent `scservo_sdk` library for Feetech servo communication.
Raw data
{
"_id": null,
"home_page": null,
"name": "vassar-feetech-servo-sdk",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": "Vassar Robotics <hello@vassarrobotics.com>",
"keywords": "robotics, servo, feetech, serial, hardware, sts, hls, control",
"author": null,
"author_email": "Vassar Robotics <hello@vassarrobotics.com>",
"download_url": "https://files.pythonhosted.org/packages/25/87/29c057d968e4ba31b14e08385942ec5a54d3e43661d202733b9ab6778eab/vassar_feetech_servo_sdk-0.3.0.tar.gz",
"platform": null,
"description": "# Vassar Feetech Servo SDK\n\nA comprehensive Python SDK and command-line tool for controlling Feetech servos (STS/HLS series).\n\n## Features\n\n- \ud83d\udd0c **Auto-detection** of serial ports\n- \ud83c\udfaf **Support for STS and HLS servos** (HLS includes torque control)\n- \ud83d\udcd6 **Read positions** from single or multiple servos \n- \ud83c\udfaf **Set middle position** - Calibrate servos to position 2048\n- \u270d\ufe0f **Write position targets** (coming soon)\n- \ud83d\udcaa **Write torque targets** (coming soon)\n- \ud83d\ude80 **High-performance** group sync operations\n- \ud83d\udcca **Real-time monitoring** with configurable update rates\n- \ud83d\udc0d **Clean Python API** with servo configuration at initialization\n- \ud83d\udcbb **Command-line interface** for all operations\n- \ud83d\udd27 **Context manager support** for clean resource management\n\n## Installation\n\n### From PyPI\n\n```bash\npip install vassar-feetech-servo-sdk\n```\n\n### From Source\n\n```bash\ngit clone https://github.com/vassar-robotics/feetech-servo-sdk.git\ncd feetech-servo-sdk\npip install -e .\n```\n\n## Dependencies\n\n- Python >= 3.7\n- pyserial >= 3.5\n\nNote: The `scservo_sdk` is bundled with this package, so no separate installation is needed.\n\n## Quick Start\n\n### Command Line Usage\n\n```bash\n# Read from motors 1-6 continuously at 30Hz\nvassar-servo\n\n# Set all servos to middle position\nvassar-servo --set-middle\n\n# Read from specific motors at 60Hz\nvassar-servo --motor-ids 1,3,5 --hz 60\n\n# Use HLS servos (default is STS)\nvassar-servo --servo-type hls\n\n# Read once and exit\nvassar-servo --once\n\n# Output JSON format (useful for scripting)\nvassar-servo --once --json\n```\n\n### Python API Usage\n\n```python\nfrom vassar_feetech_servo_sdk import ServoController\n\n# Initialize controller with your servo configuration\nservo_ids = [1, 2, 3, 4, 5, 6]\ncontroller = ServoController(servo_ids=servo_ids, servo_type=\"sts\") # or \"hls\"\ncontroller.connect()\n\n# Read all configured servos\npositions = controller.read_all_positions()\nfor motor_id, pos in positions.items():\n print(f\"Motor {motor_id}: {pos} ({pos/4095*100:.1f}%)\")\n\n# Set servos to middle position\nsuccess = controller.set_middle_position()\nif success:\n print(\"All servos calibrated to middle position!\")\n\ncontroller.disconnect()\n\n# Using context manager\nwith ServoController([1, 2, 3], \"sts\") as controller:\n positions = controller.read_all_positions()\n print(positions)\n```\n\n### Changing Servo IDs\n\n```python\nfrom vassar_feetech_servo_sdk import ServoController\n\n# Connect to a servo with current ID 1\ncontroller = ServoController(servo_ids=[1], servo_type=\"sts\")\ncontroller.connect()\n\n# Change its ID from 1 to 10\nsuccess = controller.set_motor_id(\n current_id=1,\n new_id=10,\n confirm=True # Will ask for user confirmation\n)\n\nif success:\n print(\"ID changed! Power cycle the servo to apply.\")\n \ncontroller.disconnect()\n\n# After power cycling, connect with new ID\ncontroller = ServoController(servo_ids=[10], servo_type=\"sts\")\ncontroller.connect()\n```\n\n### Advanced Usage\n\n```python\n# Initialize with specific configuration\ncontroller = ServoController(\n servo_ids=[1, 2, 3, 4, 5, 6],\n servo_type=\"hls\", # 'sts' or 'hls'\n port=\"/dev/ttyUSB0\",\n baudrate=1000000\n)\n\n# Error handling\nfrom vassar_feetech_servo_sdk import ServoReaderError, PortNotFoundError\n\ntry:\n controller = ServoController([1, 2, 3], \"sts\")\n controller.connect()\n positions = controller.read_all_positions()\nexcept PortNotFoundError:\n print(\"No servo port found!\")\nexcept ServoReaderError as e:\n print(f\"Error: {e}\")\n```\n\n## API Reference\n\n### ServoController Class\n\n#### Constructor\n\n```python\nServoController(servo_ids, servo_type=\"sts\", port=None, baudrate=1000000)\n```\n\n- `servo_ids`: List of servo IDs to control (e.g., [1, 2, 3, 4, 5, 6])\n- `servo_type`: Type of servo - 'sts' or 'hls' (default: 'sts')\n- `port`: Serial port path (auto-detect if None)\n- `baudrate`: Communication speed (default: 1000000)\n\n#### Methods\n\n- `connect()`: Establish connection to servos\n- `disconnect()`: Close connection\n- `read_position(motor_id)`: Read single motor position\n- `read_positions(motor_ids=None)`: Read multiple motor positions\n- `read_all_positions()`: Read all configured servo positions\n- `set_middle_position(motor_ids=None)`: Calibrate servos to middle position (2048)\n- `set_motor_id(current_id, new_id, confirm=True)`: Change a servo's ID (requires power cycle)\n\n### Utility Functions\n\n- `find_servo_port()`: Auto-detect servo serial port\n\n## Servo Types\n\n- **STS**: Standard Feetech servos (default) - position and speed control\n - Middle position calibration uses torque=128 method\n- **HLS**: High-end servos with additional torque control capabilities\n - Middle position calibration uses offset calibration (`reOfsCal`) method\n\n## Troubleshooting\n\n### Port Not Found\n\nIf auto-detection fails, specify the port manually:\n\n```bash\n# Linux\nvassar-servo --port /dev/ttyUSB0\n\n# macOS\nvassar-servo --port /dev/tty.usbserial-*\n\n# Windows\nvassar-servo --port COM3\n```\n\n### Permission Denied (Linux)\n\nOption 1: Add your user to the dialout group (recommended):\n\n```bash\nsudo usermod -a -G dialout $USER\n# Log out and back in for changes to take effect\n```\n\nOption 2: Grant permissions to the serial port (temporary):\n\n```bash\nsudo chmod 666 /dev/ttyUSB0\n# Replace /dev/ttyUSB0 with your actual serial port\n```\n\n### Connection Failed\n\n1. Check servo power supply\n2. Verify baudrate matches servo configuration (default: 1000000)\n3. Ensure proper wiring (TX/RX not swapped)\n\n## Examples\n\nThe package includes several example scripts in the `examples/` directory:\n\n- `basic_usage.py` - Simple example showing how to connect and read servo positions\n- `continuous_reading.py` - Real-time monitoring with custom callbacks\n- `servo_types.py` - Demonstrates differences between STS and HLS servos\n- `set_middle_position.py` - Shows how to calibrate servos to middle position\n\n## Testing\n\nRun the test suite:\n\n```bash\n./run_tests.sh # Installs dev dependencies and runs tests with coverage\n# or\npip install -r requirements-dev.txt\npython -m pytest tests/ -v\n```\n\n## Acknowledgments\n\nBuilt on top of the excellent `scservo_sdk` library for Feetech servo communication.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Vassar Robotics' Python SDK for Feetech servo control and position reading",
"version": "0.3.0",
"project_urls": {
"Homepage": "https://github.com/vassar-robotics/feetech-servo-sdk",
"Issues": "https://github.com/vassar-robotics/feetech-servo-sdk/issues",
"Repository": "https://github.com/vassar-robotics/feetech-servo-sdk"
},
"split_keywords": [
"robotics",
" servo",
" feetech",
" serial",
" hardware",
" sts",
" hls",
" control"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "e143268ac4b8c7e484643a9c895b9cbb4215ac1e6ce37929af1f6c40c978b640",
"md5": "a40445c8696fbd0a7d59721747716ad9",
"sha256": "0324476fd922ff01c133edc2557417cfbb9cb903ee590bc6348c82ba752f4a58"
},
"downloads": -1,
"filename": "vassar_feetech_servo_sdk-0.3.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "a40445c8696fbd0a7d59721747716ad9",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 27599,
"upload_time": "2025-08-06T20:40:50",
"upload_time_iso_8601": "2025-08-06T20:40:50.760147Z",
"url": "https://files.pythonhosted.org/packages/e1/43/268ac4b8c7e484643a9c895b9cbb4215ac1e6ce37929af1f6c40c978b640/vassar_feetech_servo_sdk-0.3.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "258729c057d968e4ba31b14e08385942ec5a54d3e43661d202733b9ab6778eab",
"md5": "452fc51d2bc5770763ed3146fc955118",
"sha256": "f81dafc7de90d7194fa674a6d45d71c28ebec37aeca21b41c790a86dfa75e487"
},
"downloads": -1,
"filename": "vassar_feetech_servo_sdk-0.3.0.tar.gz",
"has_sig": false,
"md5_digest": "452fc51d2bc5770763ed3146fc955118",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 27349,
"upload_time": "2025-08-06T20:40:51",
"upload_time_iso_8601": "2025-08-06T20:40:51.885292Z",
"url": "https://files.pythonhosted.org/packages/25/87/29c057d968e4ba31b14e08385942ec5a54d3e43661d202733b9ab6778eab/vassar_feetech_servo_sdk-0.3.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-06 20:40:51",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "vassar-robotics",
"github_project": "feetech-servo-sdk",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "vassar-feetech-servo-sdk"
}