Metadata-Version: 2.4
Name: raccoon-cli
Version: 0.1.94
Summary: Toolchain CLI for Botball robot development on Raspberry Pi (Wombat)
Author: Tobias Madlberger
License: GPL-3.0-only
Keywords: botball,robotics,raspberry-pi,cli,codegen
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Education
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Build Tools
Classifier: Topic :: Software Development :: Embedded Systems
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: COPYING
Requires-Dist: pyyaml
Requires-Dist: ruamel.yaml>=0.17
Requires-Dist: click>=8.0
Requires-Dist: black
Requires-Dist: rich>=10.0
Requires-Dist: questionary>=2.0
Requires-Dist: setuptools>=61.0
Requires-Dist: wheel>=0.45.1
Requires-Dist: jinja2>=3.0
Requires-Dist: jinja2-time>=0.2
Requires-Dist: fastapi>=0.100
Requires-Dist: uvicorn[standard]>=0.20
Requires-Dist: websockets>=10.0
Requires-Dist: paramiko>=4.0
Requires-Dist: httpx>=0.24
Requires-Dist: websocket-client>=1.0
Requires-Dist: pyftpsync>=4.0
Requires-Dist: libcst>=1.0.0
Requires-Dist: pydantic>=2.0
Requires-Dist: lcm
Requires-Dist: raccoon-transport>=0.1
Requires-Dist: raccoon-stubs
Dynamic: license-file

<div align="center">

<img src="https://raw.githubusercontent.com/htl-stp-ecer/.github/main/profile/raccoon-logo.svg" alt="raccoon-cli" width="100"/>

# raccoon-cli

**The dev toolchain for RaccoonOS — scaffold, configure, sync, and run Botball robots.**

[![Build & Release](https://github.com/htl-stp-ecer/raccoon-cli/actions/workflows/build-release.yml/badge.svg)](https://github.com/htl-stp-ecer/raccoon-cli/actions/workflows/build-release.yml)
[![Latest Release](https://img.shields.io/github/v/release/htl-stp-ecer/raccoon-cli)](https://github.com/htl-stp-ecer/raccoon-cli/releases/latest)
[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](COPYING)
![Python](https://img.shields.io/badge/Python-3.11+-3776AB?logo=python&logoColor=ffdd54)
![PyPI](https://img.shields.io/pypi/v/raccoon-cli?logo=pypi&logoColor=white)
![Platform](https://img.shields.io/badge/Platform-KIPR%20Wombat-orange)

> 📖 **Full documentation at [raccoon-docs.pages.dev](https://raccoon-docs.pages.dev/)**

</div>

---

`raccoon` is the command-line companion to [RaccoonLib](https://github.com/htl-stp-ecer/raccoon-lib). It handles everything outside the robot code itself: creating projects, generating hardware boilerplate from a YAML config, syncing files to the Pi, and running your missions remotely.

---

## Installation

```bash
pip install raccoon-cli
```

---

## Quick Start

```bash
# 1. Create a new project (runs the hardware wizard automatically)
raccoon create project MyRobot
cd MyRobot

# 2. Connect to your Pi
raccoon connect 192.168.4.1

# 3. Sync + run
raccoon run
```

That's it. `raccoon run` regenerates any stale code, syncs changed files to the Pi, and streams output back to your terminal.

---

## How it works

raccoon uses a **client-server architecture**. Your laptop runs the CLI; the Pi runs a small FastAPI daemon (`raccoon-server`) that receives commands, manages execution, and streams logs back.

### Pi setup (one time)

```bash
# On the Pi -- install raccoon-server as a systemd service
sudo raccoon-server install
```

After that, the server starts automatically on boot and `raccoon connect` can reach it.

---

## Commands

### Project management

| Command | Description |
|:--------|:------------|
| `raccoon create project <name>` | Scaffold a new project and run the hardware wizard |
| `raccoon create mission <name>` | Add a new mission to the current project |
| `raccoon list projects` | List all projects in the current directory |
| `raccoon list missions` | List missions in the current project |
| `raccoon remove mission <name>` | Remove a mission |
| `raccoon reorder` | Interactively reorder missions |

### Hardware & code generation

| Command | Description |
|:--------|:------------|
| `raccoon wizard` | Re-run the interactive hardware configuration |
| `raccoon codegen` | Regenerate `src/hardware/defs.py` and `src/hardware/robot.py` from config |
| `raccoon calibrate` | Two-phase calibration: measure encoder ticks/rev, then run autotune |

### Remote development

| Command | Description |
|:--------|:------------|
| `raccoon connect <address>` | Connect to a Pi server |
| `raccoon disconnect` | Disconnect from the current Pi |
| `raccoon status` | Show connection status |
| `raccoon sync` | Sync changed files to the Pi (uses content hashing) |
| `raccoon sync --force` | Re-upload all files |
| `raccoon run` | Regenerate code, sync, and run on the Pi |

### Debugging

| Command | Description |
|:--------|:------------|
| `raccoon lcm spy` | Live-inspect LCM messages on the bus |
| `raccoon lcm record <file>` | Record LCM traffic to a file |
| `raccoon checkpoint list` | List saved checkpoints |
| `raccoon checkpoint restore <id>` | Restore project to a checkpoint |

### Tooling

| Command | Description |
|:--------|:------------|
| `raccoon update` | Update raccoon-cli to the latest version |
| `raccoon completion` | Install shell tab-completion |
| `raccoon web` | Launch the web IDE |

---

## Project structure

`raccoon create project` generates:

```
MyRobot/
├── raccoon.project.yml    # Hardware config -- motors, sensors, drivetrain, connection
├── src/
│   ├── main.py
│   ├── hardware/
│   │   ├── defs.py        # Generated -- do not edit by hand
│   │   └── robot.py       # Generated -- do not edit by hand
│   ├── missions/
│   │   ├── setup_mission.py
│   │   └── shutdown_mission.py
│   └── steps/
└── .raccoonignore         # match patterns excluded from sync
```

`defs.py` and `robot.py` are regenerated by `raccoon codegen` (and automatically on every `raccoon run`). Edit `raccoon.project.yml` or re-run `raccoon wizard` to change hardware config - never edit the generated files directly.

---

## Configuration

`raccoon create project` generates a split config layout. The root file just glues things together:

### `raccoon.project.yml`

```yaml
name: MyRobot
uuid: <auto-generated>

robot:       !include 'config/robot.yml'
missions:    !include 'config/missions.yml'
definitions: !include 'config/hardware.yml'
connection:  !include 'config/connection.yml'
```

### `config/hardware.yml` -- sensors, motors, servos

```yaml
button:
  type: DigitalSensor
  port: 10
imu:
  type: IMU
front_left_ir_sensor:
  type: IRSensor
  port: 1
front_right_ir_sensor:
  type: IRSensor
  port: 2

_motors: !include-merge 'motors.yml'
_servos: !include-merge 'servos.yml'
```

### `config/motors.yml`

```yaml
left_motor:
  type: Motor
  port: 0
  inverted: false
  calibration:
    ticks_to_rad: 0.00002   # set by raccoon calibrate
    vel_lpf_alpha: 1.0
right_motor:
  type: Motor
  port: 1
  inverted: true
  calibration:
    ticks_to_rad: 0.00002
    vel_lpf_alpha: 1.0
```

### `config/connection.yml`

```yaml
pi_address: 192.168.4.1
pi_port: 8421
pi_user: pi
auto_connect: true
```

### `~/.raccoon/config.yml` (global)

```yaml
known_pis:
  - hostname: raccoon-pi
    address: 192.168.4.1
default_pi_user: pi
```

---

## Part of RaccoonOS

| Repository | What it is |
|:-----------|:-----------|
| [raccoon-lib](https://github.com/htl-stp-ecer/raccoon-lib) | Core robotics library |
| [raccoon-example](https://github.com/htl-stp-ecer/raccoon-example) | Reference robot -- start here if you're new |
| [raccoon-transport](https://github.com/htl-stp-ecer/raccoon-transport) | LCM messaging layer |
| [documentation](https://raccoon-docs.pages.dev/) | Full platform docs |

---

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for how to get started contributing


## License

Copyright (C) 2026 Tobias Madlberger  
Licensed under the GNU General Public License v3.0 -- see [COPYING](COPYING) for details.
