# FeatherCLI `feathercli` is the command-line tool installed with the Feather SDK. Use it to install the robot onto the machine, configure the Teensy ethernet link, scan and flash motors, change a Robstride motor's id, teleoperate, and copy the example notebook. Run `feathercli --help` (or `feathercli --help`) for the live flag list. ## Commands ### --> `feathercli install` Install Feather onto the machine, or verify that a previous install looks correct. `--all` copies the versioned configs, installs conda and the required apt packages, and configures the Teensy ethernet link. ```bash sudo feathercli install --all -v YOUR_VERSION feathercli install --verify ``` `YOUR_VERSION` must match a bundled config set (for example `v0.5.1`). The available values are the directory names under the SDK's `configs/user_configs/` package data; `feathercli install --help` lists the current choices. This requires `sudo` privelages when installing certain files/packages. :::{note} If `feathersdk` is not installed in your system /usr/bin/python environment, `sudo` won't be able to find the correct `feathercli`. You would instead need to activate your environment you wish to use and run: ```bash sudo -E $(which feathercli) install --all -v YOUR_VERSION ``` ::: `--all` turns on every install step. Each step also has its own flag, and a matching `--no-install-*` flag turns that step back off even when `--all` is set. Passing both the enable flag and its `--no-install-*` pair is an error. With no step flags, the command installs nothing. | Flag | Description | | --- | --- | | `-a`, `--all` | Install configs, conda, system packages, and the Teensy ethernet link. | | `-c`, `--configs` | Copy the versioned robot configs. Required unless you pass `--all`. | | `--no-install-configs` | Skip copying configs, including when `--all` is set. | | `-v`, `--version` | Robot revision to install. Required when installing configs. | | `-o`, `--output` | Root directory to install into. Defaults to `/feathersys`. | | `-f`, `--force` | Overwrite an existing configs directory. Without this flag, an existing destination raises an error. | | `--install-conda` | Install Archiconda for the login user if it is not already present, and source `conda.sh` from `.bashrc`. | | `--no-install-conda` | Skip the conda install, including when `--all` is set. | | `--install-system-packages` | Install missing apt packages `make` and `libnss-mdns`. | | `--no-install-system-packages` | Skip system packages, including when `--all` is set. | | `--install-setup-ethernet` | Configure the Jetson ethernet link to the Teensy. Same behavior as `feathercli setup-ethernet`. | | `--no-install-setup-ethernet` | Skip ethernet setup, including when `--all` is set. | | `--setup-ethernet-method` | `static` or `dhcp`. Default: dhcp if a DHCP server answers, otherwise static `192.168.10.1/24`. | | `--verify` | Check that the install looks correct. Does not copy or overwrite anything. | `--verify` confirms that: * key folders/files exist and are accessible. * the robot config file imports successfully. --- ### --> `feathercli control` Start an interactive teleop session. The robot is initialized from the system configs unless you pass `--configs`. ```bash feathercli control keyboard feathercli control ps4 feathercli control keyboard --configs /path/to/configs ``` `control_method` is one of `keyboard`/`k`, or `ps4`. | Flag | Description | | --- | --- | | `control_method` | How to drive the robot: `keyboard` / `k`, or `ps4`. | | `-c`, `--configs` | Path to the configs to load. Defaults to the system configs. | Both modes initialize a `FeatherRobot` and stop motion on exit. #### Keyboard ```bash feathercli control keyboard ``` Use the keyboard to control the robot. | Keys | Action | | --- | --- | | `w` `a` `s` `d` | Forward / left / backward / right | | `q` `e` | Rotate left / right (combine with WASD) | | `r` `f` | Torso up / down | | `i` `j` `k` `l` | Neck up / left / down / right | | `<` `>` | Decrease / increase speed multiplier | | `Ctrl+C` | Exit | #### PS4 controller ```bash feathercli control ps4 ``` Use a ps4 controller to control the robot. Requires [pygame](https://www.pygame.org/) (`pip install pygame`) and a connected DualShock 4. | Control | Action | | --- | --- | | Left stick | Holonomic translate (forward/back, left/right) | | Right stick | Yaw (left/right only; up/down is ignored) | | L2 / R2 | Torso down / up | | D-pad | Neck pitch (up/down) and yaw (left/right) | | Circle (`O`) | Abort the robot and exit | | `Ctrl+C` | Quit and stop the base and torso | To pair a DualShock 4 over Bluetooth, hold Share + PS until the lights blink, then: ```bash bluetoothctl power on agent on default-agent scan on # wait for "Wireless Controller" pair XX:XX:XX:XX:XX:XX trust XX:XX:XX:XX:XX:XX connect XX:XX:XX:XX:XX:XX ``` NOTE: On startup the command samples the pad at rest and picks an axis layout, so keep the sticks centered and the triggers released for about half a second. --- ### --> `feathercli example` Copy the bundled `feathersdk_example.ipynb` notebook into a working directory. The notebook shows `initialize_feather_system()` and a few motion snippets. ```bash feathercli example feathercli example -o /path/to/dir feathercli example -o ./my_notebook.ipynb ``` | Flag | Description | | --- | --- | | `-o`, `--output` | Destination path. Defaults to `./feathersdk_example.ipynb`. If the path is an existing directory, the notebook is copied into it with the same filename. | --- ### --> `feathercli setup-ethernet` Configure the Jetson ethernet NIC used to reach the Teensy. This is the same step `feathercli install --install-setup-ethernet` runs. There are two main configurations for the teensy ethernet connection: `static` (meaning the teensy is connected directly to the jetson, or through a pure ethernet switch), and `dynamic` (meaning both teensy and jetson are connected to a router/something providing dhcp service). ```bash feathercli setup-ethernet feathercli setup-ethernet static feathercli setup-ethernet dhcp ``` With no method, the command probes the ethernet port. A DHCP lease selects `dhcp`. No answer selects `static` (`192.168.10.1/24`). Auto-detect requires exactly one ethernet NIC; pass `static` or `dhcp` when there are several. | Argument | Description | | --- | --- | | `method` | Optional. `static` or `dhcp`. | If you wish to switch from one method of ethernet connection to another, you will have to run this cli command to update the jetson ethernet interface appropriately. --- ### --> `feathercli scancan` Scan the Teensy CAN buses for motors. Each id in `[0, MAX_NUM_ACTUATORS)` is initialized, then probed, unless `--ids` lists a subset. A motor counts as present when its reply moves that parameter's telemetry timestamp. By default this scans Robstride motors (`LIMIT_TORQUE`) and EZMotion motors (`POSITION`). The two motor types are scanned in separate processes. ```bash feathercli scancan feathercli scancan can0 can2 feathercli scancan --only-robstride --attempts 3 feathercli scancan --ids=1,4,0x43 ``` Bus names are Teensy bus indexes (`can0`, `can1`, `vcan0`), not host SocketCAN device names. | Flag | Description | | --- | --- | | `IFACE` | Optional bus names. Default: every bus the Teensy reports. | | `-c`, `--configs` | Robot config path. Defaults to the system robot config. Only needed to know if we are using real/emulated teensy. | | `--only-robstride` | Scan Robstride motors only. | | `--only-ezmotion` | Scan EZMotion motors only. Mutually exclusive with `--only-robstride`. | | `--delay` | Seconds between transmit frames. Default: `0.002`. | | `--wait` | Seconds to wait for replies after a probe burst. Default: `0.05`. | | `--attempts` | Probe attempts per bus. Default: `1`. | | `--ids` | Comma-separated ids to probe instead of every id in `[0, MAX_NUM_ACTUATORS)`, decimal or hex (for example `1,4,0x43`). | --- ### --> `feathercli flash-motor` Download the known-good Robstride firmware bins (if they are not already cached) and flash every Robstride motor found on the Teensy CAN buses, or only the ids you list. EZMotion motors found by the scan are left alone. Bins are cached under `~/.cache/feathersdk/rob_bins`. A motor whose version already matches that file is skipped unless you pass `--force`. ```bash feathercli flash-motor feathercli flash-motor 3 0x15 feathercli flash-motor --force --progress=False feathercli flash-motor -c /path/to/robot_config.py ``` | Flag | Description | | --- | --- | | `ID` | Optional motor ids, decimal or hex. Default: every Robstride motor that answers. Ids must be in `[0, MAX_NUM_ACTUATORS)`. | | `--force` | Flash even when the motor already has this firmware version. | | `--progress` | `True` or `False`. Show a progress bar while sending firmware packets. Default: `True`. | | `-c`, `--configs` | Robot config path. Defaults to the system robot config. Only needed to know if we are using real/emulated teensy. | --- ### --> `feathercli set-motor-id` Change one Robstride motor's CAN id. EZMotion motors are not supported. The command scans for `old_id` and `new_id` as Robstride motors. `old_id` must answer on exactly one bus; if it answers on more than one, pass `--iface`. The change is refused when `new_id` already answers on that same bus. After the id is written, the command reads `LIMIT_TORQUE` from `new_id` and fails if that motor does not reply. Ids are decimal or hex and must be in `[0, MAX_NUM_ACTUATORS)`. `old_id` and `new_id` must differ. ```bash feathercli set-motor-id 1 0x43 feathercli set-motor-id 3 0x15 --iface can0 feathercli set-motor-id 4 5 -c /path/to/robot_config.py ``` | Flag | Description | | --- | --- | | `old_id` | Current Robstride motor id. | | `new_id` | Id to assign. Must not already answer on the same bus as `old_id`. | | `--iface` | Teensy bus to scan, for example `can0`. Default: every bus the Teensy reports. | | `-c`, `--configs` | Robot config path. Defaults to the system robot config. Only needed to know if we are using real/emulated teensy. |