Skip to content

Commit 07be344

Browse files
authored
Merge pull request #12 from Jepson2k/faster-kinematics
Faster kinematics
2 parents 75232e7 + 6cf0f41 commit 07be344

101 files changed

Lines changed: 14055 additions & 9929 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/tests.yml‎

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
name: tests
2+
3+
on:
4+
push:
5+
paths:
6+
- '**'
7+
pull_request:
8+
paths:
9+
- '**'
10+
11+
jobs:
12+
lint:
13+
name: Lint (ruff + mypy)
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Checkout repository
17+
uses: actions/checkout@v4
18+
- name: Setup Python
19+
uses: actions/setup-python@v5
20+
with:
21+
python-version: '3.11'
22+
cache: pip
23+
cache-dependency-path: pyproject.toml
24+
- name: Install dev dependencies
25+
run: |
26+
python -m pip install --upgrade pip
27+
pip install -e ".[dev]"
28+
- name: Ruff (lint)
29+
run: ruff check parol6
30+
- name: Ruff (format check)
31+
run: ruff format --check parol6
32+
- name: MyPy
33+
run: mypy parol6
34+
test:
35+
name: ${{ matrix.os }} / Python ${{ matrix.python-version }}
36+
runs-on: ${{ matrix.os }}
37+
timeout-minutes: 30
38+
strategy:
39+
fail-fast: false
40+
matrix:
41+
os: [ubuntu-latest, windows-latest, macos-latest]
42+
python-version: ['3.10', '3.11']
43+
44+
steps:
45+
- name: Checkout repository (with submodules)
46+
uses: actions/checkout@v4
47+
48+
- name: Setup Python
49+
uses: actions/setup-python@v5
50+
with:
51+
python-version: ${{ matrix.python-version }}
52+
cache: pip
53+
cache-dependency-path: pyproject.toml
54+
55+
- name: Upgrade pip and install dependencies
56+
run: |
57+
python -m pip install --upgrade pip
58+
pip install -e ".[dev]" pytest-timeout
59+
60+
- name: Show environment
61+
run: |
62+
python -V
63+
pip list
64+
65+
- name: Run tests (skip hardware)
66+
env:
67+
PYTHONUNBUFFERED: '1'
68+
PYTHONUTF8: '1'
69+
run: |
70+
pytest

‎.gitignore‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,4 +124,4 @@ cython_debug/
124124
# VS Code
125125
.vscode/
126126

127-
serial_port.txt
127+
serial_port.txt

‎.pre-commit-config.yaml‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
default_language_version:
2+
python: python3.11
3+
4+
repos:
5+
- repo: https://github.com/pre-commit/pre-commit-hooks
6+
rev: v4.6.0
7+
hooks:
8+
- id: check-yaml
9+
- id: end-of-file-fixer
10+
- id: trailing-whitespace
11+
- id: check-merge-conflict
12+
- id: check-added-large-files
13+
14+
- repo: https://github.com/astral-sh/ruff-pre-commit
15+
rev: v0.6.9
16+
hooks:
17+
- id: ruff
18+
args: ["--fix"]
19+
- id: ruff-format
20+
21+
- repo: https://github.com/pre-commit/mirrors-mypy
22+
rev: v1.11.2
23+
hooks:
24+
- id: mypy
25+
name: mypy (parol6)
26+
files: ^parol6/
27+
pass_filenames: false
28+
args: ["parol6"]
29+
stages: [commit, push]
30+
additional_dependencies:
31+
- numpy==1.26.4
32+
- spatialmath-python==1.1.14
33+
- scipy==1.11.4

‎README.md‎

Lines changed: 226 additions & 898 deletions
Large diffs are not rendered by default.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
"""
2+
Async client quickstart for PAROL6.
3+
- Starts a local headless controller at 127.0.0.1:5001
4+
- Enables simulator mode for safety
5+
- Shows basic queries and status streaming
6+
7+
Run from the repository root:
8+
python external/PAROL6-python-API/examples/async_client_quickstart.py
9+
"""
10+
11+
import asyncio
12+
from parol6 import AsyncRobotClient
13+
from parol6.client.manager import managed_server
14+
15+
HOST = "127.0.0.1"
16+
PORT = 5001
17+
18+
19+
async def run_client() -> int:
20+
async with AsyncRobotClient(host=HOST, port=PORT, timeout=2.0) as client:
21+
ready = await client.wait_for_server_ready(timeout=5.0)
22+
print(f"server ready: {ready}")
23+
if not ready:
24+
return 1
25+
26+
# Safety: enable simulator for this demo
27+
ok = await client.simulator_on()
28+
print(f"simulator_on: {ok}")
29+
30+
print("ping:", await client.ping())
31+
pose_xyz = await client.get_pose_xyz()
32+
print("pose xyz:", pose_xyz)
33+
34+
# Consume one status broadcast
35+
print("one status frame speeds:")
36+
async for status in client.status_stream():
37+
print(status.get("speeds"))
38+
break
39+
40+
# Small relative TRF move (safe in simulator)
41+
# Move +5mm in Z over 1.0s
42+
moved = await client.move_cartesian_rel_trf([0, 0, 5, 0, 0, 0], duration=1.0)
43+
print("move_cartesian_rel_trf ->", moved)
44+
45+
return 0
46+
47+
48+
def main() -> None:
49+
# Auto-start and stop controller for this example
50+
with managed_server(host=HOST, port=PORT, normalize_logs=True):
51+
code = asyncio.run(run_client())
52+
raise SystemExit(code)
53+
54+
55+
if __name__ == "__main__":
56+
main()

‎examples/manage_server_demo.py‎

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
"""
2+
Manage server lifecycle demonstration for PAROL6.
3+
- Starts a local headless controller at 127.0.0.1:5001
4+
- Waits until ready, then connects with RobotClient
5+
- Toggles simulator ON for a safe demo motion, then OFF
6+
- Stops the controller on exit
7+
8+
Run from the repository root:
9+
python external/PAROL6-python-API/examples/manage_server_demo.py
10+
"""
11+
12+
from parol6 import manage_server, RobotClient
13+
14+
HOST = "127.0.0.1"
15+
PORT = 5001
16+
17+
18+
def main() -> None:
19+
mgr = manage_server(host=HOST, port=PORT, normalize_logs=True)
20+
try:
21+
with RobotClient(host=HOST, port=PORT, timeout=2.0) as client:
22+
ready = client.wait_for_server_ready(timeout=5.0)
23+
print(f"server ready: {ready}")
24+
if not ready:
25+
raise SystemExit(1)
26+
27+
print("ping:", client.ping())
28+
29+
# Enable simulator for a safe motion
30+
sim_on = client.simulator_on()
31+
print("simulator_on:", sim_on)
32+
33+
if sim_on:
34+
# Small relative TRF move: +3mm in Z over 0.8s
35+
moved = client.move_cartesian_rel_trf([0, 0, 3, 0, 0, 0], duration=0.8)
36+
print("move_cartesian_rel_trf ->", moved)
37+
38+
# Demonstrate toggling simulator off again (no motion follows)
39+
sim_off = client.simulator_off()
40+
print("simulator_off:", sim_off)
41+
42+
raise SystemExit(0)
43+
finally:
44+
mgr.stop_controller()
45+
46+
47+
if __name__ == "__main__":
48+
main()

‎examples/sync_client_quickstart.py‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
"""
2+
Sync client quickstart for PAROL6.
3+
- Assumes a controller is already running at 127.0.0.1:5001
4+
- Does not enable simulator in this example
5+
- Performs ping and basic queries
6+
7+
Run from the repository root:
8+
python external/PAROL6-python-API/examples/sync_client_quickstart.py
9+
"""
10+
11+
from parol6 import RobotClient
12+
13+
HOST = "127.0.0.1"
14+
PORT = 5001
15+
16+
17+
def main() -> None:
18+
with RobotClient(host=HOST, port=PORT, timeout=2.0) as client:
19+
ready = client.wait_for_server_ready(timeout=3.0)
20+
print(f"server ready: {ready}")
21+
print("ping:", client.ping())
22+
print("pose xyz:", client.get_pose_xyz())
23+
print("angles:", client.get_angles())
24+
code = 0 if ready else 1
25+
raise SystemExit(code)
26+
27+
28+
if __name__ == "__main__":
29+
main()

0 commit comments

Comments
 (0)