Files
wrickertandClaude Opus 5.5 4e957509cc Ruida laser skill: prepare and load jobs, never run them
FreeCAD/DXF to .rd conversion, named upload to controller memory with
idle check and read-back verification, read-only status/file listing,
and a fake controller for dry runs.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 10:24:05 -05:00

75 lines
3.6 KiB
Markdown

# RuidaSkill
Let Claude (or another LLM agent) prepare laser jobs for a **Ruida-controlled CO2 laser** and
load them into the controller's memory over the network, with no LightBurn or RDWorks. You still
start every job yourself at the laser's panel.
Built for the [Tangent Heavy Industries](https://tangentheavy.com) shop's 60 W "black and red"
laser (RDC644x-class controller), and used to cut real parts.
Short link: **https://git.tangentheavy.com/RuidaSkill**
## What it does
```
FreeCAD body ──fc2dxf.py──▶ DXF ──dxf2rd.py──▶ JOB.rd ──rdupload.py──▶ controller memory
rdlist.py ◀── busy/idle + stored files
```
- **`fc2dxf.py`**: takes a sheet part from a FreeCAD model and writes its outline as a DXF. It cuts holes before the outline and refuses parts the laser can't cut through.
- **`dxf2rd.py`**: turns the DXF into a Ruida job file with speed, min/max power, passes and air assist. It works offline and has no network code.
- **`rdupload.py`**: stores the job on the controller under a name. It refuses while a job is running or if the name is already taken, then reads the file list back to prove the file landed.
- **`rdlist.py`**: read-only status and file list. It checks every outgoing byte against a whitelist, so it can't send delete or start.
- **`fake_ruida.py`**: a fake controller on localhost for dry runs. It logs every command it receives.
## The rule
**The agent never fires the laser.** It prepares files and loads them; a person checks the
material, coolant, air and exhaust, frames the job and presses Start. A CO2 laser can start a
fire, and firing without coolant can crack the tube. The scripts enforce this: there is no code
path that sends start, frame, move or delete commands. See the Safety section of
[`ruida-laser/SKILL.md`](ruida-laser/SKILL.md).
## Install
```bash
git clone https://git.tangentheavy.com/RuidaSkill.git
python3 -m venv ~/.local/share/ruida-venv
~/.local/share/ruida-venv/bin/pip install meerk40t
```
[MeerK40t](https://github.com/meerk40t/meerk40t) (MIT) is used only as a library for the `.rd`
file format. The plain package pulls in numpy, pyusb and pyserial, no GUI.
**Claude Code:** copy or symlink the skill folder into your skills directory:
```bash
ln -s "$PWD/RuidaSkill/ruida-laser" ~/.claude/skills/ruida-laser
```
Then ask, for example: *"Export the Side body from Box.FCStd and load it on the laser as SIDE01."*
Tell Claude your controller's IP once (it's on the panel's network settings screen, or LightBurn's
device Info), and keep it in your project's `CLAUDE.md`.
**Other agents (Codex, Cursor, Aider, local models):** `ruida-laser/SKILL.md` is plain Markdown.
Point the agent at it (this repo's `AGENTS.md` does that), or paste it into the system prompt.
The scripts are ordinary command-line tools and work without any agent:
```bash
PY=~/.local/share/ruida-venv/bin/python
$PY ruida-laser/scripts/dxf2rd.py part.dxf part.rd --speed 25 --max 65 --min 55 --passes 2 --air
$PY ruida-laser/scripts/rdlist.py --host 192.0.2.10
$PY ruida-laser/scripts/rdupload.py part.rd --name PART01 --host 192.0.2.10 --confirm
```
## Compatibility
Tested on one RDC644x-class controller over Ethernet (UDP), swizzle magic 0x88. Other Ruida
models probably work. If nothing ACKs, the magic is the first suspect. USB is not supported.
[`references/protocol.md`](ruida-laser/references/protocol.md) lists exactly what was confirmed
on hardware and what is taken from MeerK40t and LibLaserCut.
## License
MIT. See [LICENSE](LICENSE). Use at your own risk: you are responsible for what your laser does.