diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
index 3a5df5cd..368057d4 100644
--- a/.devcontainer/Dockerfile
+++ b/.devcontainer/Dockerfile
@@ -17,9 +17,15 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
python3-numpy \
libboost-python-dev \
libopencv-dev \
- python3-opencv
+ python3-opencv \
+ ros-humble-cv-bridge
+
+RUN echo "/opt/ros/$ROS_DISTRO/lib" > /etc/ld.so.conf.d/ros2.conf \
+ && echo "/opt/ros/$ROS_DISTRO/lib/$(dpkg-architecture -qDEB_HOST_MULTIARCH)" >> /etc/ld.so.conf.d/ros2.conf \
+ && ldconfig
RUN pip3 install --no-cache-dir \
+ "numpy<2" \
moteus \
pyusb \
pybind11 \
@@ -55,11 +61,11 @@ RUN useradd trickfire --shell /bin/bash --create-home --no-log-init -G video,sud
&& touch /home/trickfire/.sudo_as_admin_successful \
&& chown trickfire:trickfire /home/trickfire/.sudo_as_admin_successful
-# trickfire is non-root, but SocketCAN raw sockets (candump/cansend and the RMD-X8
-# node's CanDriver) need CAP_NET_RAW/CAP_NET_ADMIN, which a non-root exec doesn't get
-# just from the container's `cap_add`/`privileged` settings. Grant NOPASSWD sudo for
-# only the specific CAN tooling and the built can_rmdx8 node so this works without an
-# interactive password, without handing trickfire unrestricted root.
+# Bringing the CAN link up needs CAP_NET_ADMIN, which non-root trickfire doesn't get just
+# from the container's `privileged` setting, so grant NOPASSWD sudo for the CAN tooling
+# that setup-can-network.sh drives. The can_rmdx8 node is deliberately NOT listed here: it
+# has to run as trickfire like the rest of the ROS graph or cross-user FastDDS shared
+# memory drops its traffic, and an AF_CAN raw socket needs no capability to open.
COPY .devcontainer/trickfire-can-sudoers /etc/sudoers.d/trickfire-can
RUN chmod 0440 /etc/sudoers.d/trickfire-can && visudo -cf /etc/sudoers.d/trickfire-can
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index 3f177b6e..45736447 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -1,8 +1,8 @@
{
"dockerComposeFile": "docker-compose.yml",
"service": "viator",
- "workspaceFolder": "/home/trickfire/urc-2023",
- "postCreateCommand": "pre-commit install",
+ "workspaceFolder": "/home/trickfire/viator",
+ "postCreateCommand": "make hooks",
"customizations": {
"vscode": {
"extensions": [
diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml
index fa5c8599..b39b6842 100644
--- a/.devcontainer/docker-compose.yml
+++ b/.devcontainer/docker-compose.yml
@@ -4,12 +4,12 @@ services:
context: ..
dockerfile: .devcontainer/Dockerfile
target: viator
- image: urc-2023:latest
+ image: viator:latest
container_name: viator
user: trickfire
volumes:
- - ..:/home/trickfire/urc-2023
+ - ..:/home/trickfire/viator
# - /dev/video0:/dev/video0
- type: bind
source: ${HOME}/.ssh
@@ -18,7 +18,7 @@ services:
bind:
create_host_path: true
- working_dir: /home/trickfire/urc-2023
+ working_dir: /home/trickfire/viator
network_mode: host
diff --git a/.devcontainer/trickfire-can-sudoers b/.devcontainer/trickfire-can-sudoers
index b545cf2b..06562fd4 100644
--- a/.devcontainer/trickfire-can-sudoers
+++ b/.devcontainer/trickfire-can-sudoers
@@ -1,3 +1 @@
-Defaults!/home/trickfire/urc-2023/install/can_rmdx8/lib/can_rmdx8/can_rmdx8 !env_reset, env_delete-="PYTHONPATH"
-
-trickfire ALL=(root) NOPASSWD: /usr/sbin/ip, /usr/sbin/modprobe, /usr/bin/candump, /usr/bin/cansend, /usr/bin/cangen, /usr/bin/cansniffer, /home/trickfire/urc-2023/install/can_rmdx8/lib/can_rmdx8/can_rmdx8
+trickfire ALL=(root) NOPASSWD: /usr/sbin/ip, /usr/sbin/modprobe, /usr/bin/candump, /usr/bin/cansend, /usr/bin/cangen, /usr/bin/cansniffer
diff --git a/.devcontainer/trickfire.bashrc b/.devcontainer/trickfire.bashrc
index 834bd39a..0a1edccd 100644
--- a/.devcontainer/trickfire.bashrc
+++ b/.devcontainer/trickfire.bashrc
@@ -22,7 +22,7 @@ fi
[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"
# ---------- ROS workspace overlay ----------
-export ROS_WS="${ROS_WS:-/home/trickfire/urc-2023}"
+export ROS_WS="${ROS_WS:-/home/trickfire/viator}"
_ros_source_env() {
if [ -f "/opt/ros/${ROS_DISTRO}/setup.bash" ]; then
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 342c687a..3e0c6fa4 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -40,12 +40,12 @@
"python.autoComplete.extraPaths": [
"/opt/ros/humble/lib/python3.10/site-packages",
"./src",
- "/home/trickfire/urc-2023/install/custom_interfaces/local/lib/python3.10/dist-packages"
+ "/home/trickfire/viator/install/custom_interfaces/local/lib/python3.10/dist-packages"
],
"python.analysis.extraPaths": [
"/opt/ros/humble/lib/python3.10/site-packages",
"./src",
- "/home/trickfire/urc-2023/install/custom_interfaces/local/lib/python3.10/dist-packages"
+ "/home/trickfire/viator/install/custom_interfaces/local/lib/python3.10/dist-packages"
],
"python.analysis.diagnosticSeverityOverrides": {
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 00000000..d6456956
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/Makefile b/Makefile
index 46f87d14..55ca2f35 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,11 @@
-.PHONY: build launch container connect can-setup sync-orin format hooks
+.PHONY: build clean launch container connect can-setup sync-orin format hooks
build:
./scripts/build.sh
+clean:
+ rm -rf build install log
+
launch:
./scripts/launch.sh
@@ -15,7 +18,7 @@ connect:
can-setup:
./scripts/setup-can-network.sh
-sync-orin:
+sync:
./scripts/sync-to-orin.sh $(IP) $(REMOTE_PATH)
format:
diff --git a/README.md b/README.md
index 2ece3dd7..e6e1a2ba 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,11 @@
# Viator
-Software developed by [Trickfire Robotics](https://www.trickfirerobotics.org/) for the Viator Rover built for the [University Rover Challenge](https://urc.marssociety.org/), using [ROS2 Humble](https://docs.ros.org/en/humble/index.html).
+Software developed by [Trickfire Robotics](https://www.trickfirerobotics.org/) for the Viator Rover built for the [University Rover Challenge](https://urc.marssociety.org/).
## Documentation
-**Full documentation is at [docs.trickfirerobotics.com/simulations](https://docs.trickfirerobotics.com/simulations).** See also our
-[Notion wiki](https://www.notion.so/trickfire/Getting-Started-With-Viator-Rover-1491fd41ff5b801485e0f6ad57e0a0aa).
+**Full documentation is at [docs.trickfirerobotics.com/simulations](https://docs.trickfirerobotics.com/viator).**
-- [Getting Started](http://docs.trickfirerobotics.com/urc-2023/getting-started) - dev environment setup
-- [Architecture](http://docs.trickfirerobotics.com/urc-2023/architecture) - architecture decisions/explanations
-- [Rover Launch](http://docs.trickfirerobotics.com/urc-2023/launching) - how to launch Viator
+- [Getting Started](http://docs.trickfirerobotics.com/viator/getting-started) - dev environment setup
+- [Architecture](http://docs.trickfirerobotics.com/viator/architecture) - architecture decisions/explanations
+- [Rover Launch](http://docs.trickfirerobotics.com/viator/launching) - how to launch Viator
diff --git a/docs/architecture.mdx b/docs/architecture.mdx
index 59459c4c..38ff94dd 100644
--- a/docs/architecture.mdx
+++ b/docs/architecture.mdx
@@ -7,7 +7,7 @@ slug: architecture
## Repo layout
```
-urc-2023/
+viator/
├── src/ # ROS 2 workspace (colcon)
│ ├── arm/ # Arm control node
│ ├── camera/ # Camera streaming node
@@ -31,13 +31,13 @@ urc-2023/
Not a ROS node itself; every node package imports from here.
-| File | Purpose |
-| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
-| `lib/configs.py` | Static motor configuration (CAN IDs, motor type, gear ratios) shared across the whole robot. |
-| `lib/interface/robot_interface.py` | `RobotInterface` — the utility class nodes use to command motors (converts between physical units and raw motor commands, publishes over the CAN bridges). |
-| `lib/interface/robot_info.py` | `RobotInfo` — the read-side counterpart: subscribes to motor state topics and exposes the current state of every motor on the robot. |
-| `lib/motor_state/` | Typed state objects for each motor backend (`CANMotorState`, `MoteusMotorState`, `RMDX8MotorState`). |
-| `lib/color_codes.py`, `lib/json_msg.py` | Small logging/serialization helpers. |
+| File | Purpose |
+| --- | --- |
+| `lib/configs.py` | Static motor configuration (CAN IDs, motor type, gear ratios) shared across the whole robot. |
+| `lib/interface/robot_interface.py` | `RobotInterface` — the utility class nodes use to command motors (converts between physical units and raw motor commands, publishes over the CAN bridges). |
+| `lib/interface/robot_info.py` | `RobotInfo` — the read-side counterpart: subscribes to motor state topics and exposes the current state of every motor on the robot. |
+| `lib/motor_state/` | Typed state objects for each motor backend (`CANMotorState`, `MoteusMotorState`, `RMDX8MotorState`). |
+| `lib/color_codes.py`, `lib/json_msg.py` | Small logging/serialization helpers. |
## Motor drivers
@@ -62,13 +62,13 @@ Two independent CAN motor controller backends, both bridging to the shared `lib/
## Robot-facing nodes
-| Node | Description |
-| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `drivebase` | Subscribes to left/right drive commands and forwards them to the wheel motors via `RobotInterface`. |
-| `arm` | Arm control; supports per-motor velocity/position control today (`individual_control_vel.py`), with inverse kinematics stubbed out as a future `ArmModeEnum` mode. Mode is switched at runtime via the `custom_interfaces/srv/ArmMode` service. |
-| `camera` | `roscamera` node (`camera/roscamera.py`) enumerates connected USB cameras and publishes compressed image streams over `sensor_msgs/CompressedImage`. |
-| `heartbeat` | Connection watchdog: if the base station connection drops, it's responsible for cutting power to the motors as a safety stop. |
-| `mission_control_updater` | Periodically collects motor state via `RobotInfo`, serializes it to JSON (`info_to_json_helper.py`), and publishes it for the mission control dashboard (delivered over `ros-humble-rosbridge-server`, installed in the Dockerfile). |
+| Node | Description |
+| --- | --- |
+| `drivebase` | Subscribes to left/right drive commands and forwards them to the wheel motors via `RobotInterface`. |
+| `arm` | Arm control; supports per-motor velocity/position control today (`individual_control_vel.py`), with inverse kinematics stubbed out as a future `ArmModeEnum` mode. Mode is switched at runtime via the `custom_interfaces/srv/ArmMode` service. |
+| `camera` | `roscamera` node (`camera/roscamera.py`) enumerates connected USB cameras and publishes compressed image streams over `sensor_msgs/CompressedImage`. |
+| `heartbeat` | Connection watchdog: if the base station connection drops, it's responsible for cutting power to the motors as a safety stop. |
+| `mission_control_updater` | Periodically collects motor state via `RobotInfo`, serializes it to JSON (`info_to_json_helper.py`), and publishes it for the mission control dashboard (delivered over `ros-humble-rosbridge-server`, installed in the Dockerfile). |
## `custom_interfaces`
diff --git a/docs/getting-started.mdx b/docs/getting-started.mdx
index d53f94e6..18fe9e93 100644
--- a/docs/getting-started.mdx
+++ b/docs/getting-started.mdx
@@ -4,39 +4,28 @@ description: Set up a development environment for the Viator rover software.
slug: /
---
-This is the software for **Viator**, Trickfire Robotics' rover for the [University Rover
-Challenge](https://urc.marssociety.org/), built on [ROS 2 Humble](https://docs.ros.org/en/humble/).
+This is the software for **Viator**, Trickfire Robotics' rover for the [University Rover Challenge](https://urc.marssociety.org/), built on [ROS 2 Humble](https://docs.ros.org/en/humble/).
## Prerequisites
- [Docker](https://docs.docker.com/get-docker/)
-- [Visual Studio Code](https://code.visualstudio.com/) with the
- [Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)
- extension
+- [Visual Studio Code](https://code.visualstudio.com/) with the [Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension
-Development happens inside a Docker container so every contributor gets the same ROS 2 Humble
-environment, regardless of host OS.
+Development happens inside a Docker container so every contributor gets the same ROS 2 Humble environment, regardless of host OS.
## Set up the dev container
1. Clone the repo (with submodules):
```bash title="Terminal"
- git clone --recurse-submodules https://github.com/TrickfireRobotics/urc-2023.git
+ git clone --recurse-submodules https://github.com/TrickfireRobotics/viator.git
```
-2. Open the folder in VS Code and choose **Reopen in Container** when prompted (or run
- **Dev Containers: Reopen in Container** from the command palette). This uses
- `.devcontainer/docker-compose.yml` to build `.devcontainer/Dockerfile` (which installs
- ROS 2 Humble, the CAN/motor tooling, and the
- [myactuator_rmd](https://github.com/2b-t/myactuator_rmd) library) and starts it as a
- container named `viator`, so it's easy to find with `docker ps`.
+2. Open the folder in VS Code and choose **Reopen in Container** when prompted (or run **Dev Containers: Reopen in Container** from the command palette). This uses `.devcontainer/docker-compose.yml` to build `.devcontainer/Dockerfile` (which installs ROS 2 Humble, the CAN/motor tooling, and the [myactuator_rmd](https://github.com/2b-t/myactuator_rmd) library) and starts it as a container named `viator`, so it's easy to find with `docker ps`.
## Build and launch
-All common actions are exposed as `make` targets from the repo root — see
-[Launching the Rover](launching) for the full workflow. The short version, from inside the
-container:
+All common actions are exposed as `make` targets from the repo root — see [Launching the Rover](launching) for the full workflow. The short version, from inside the container:
```bash title="Terminal"
make build # colcon build --symlink-install
@@ -51,20 +40,15 @@ make launch # ros2 launch viator_launch robot.launch.py
## Formatting and linting
-Python is formatted/linted with [Ruff](https://docs.astral.sh/ruff/) and type-checked with
-[mypy](https://mypy-lang.org/); shell scripts are formatted with
-[shfmt](https://github.com/mvdan/sh). Install the recommended VS Code extensions when prompted,
-or run everything manually:
+Python is formatted/linted with [Ruff](https://docs.astral.sh/ruff/) and type-checked with [mypy](https://mypy-lang.org/); shell scripts are formatted with [shfmt](https://github.com/mvdan/sh). Install the recommended VS Code extensions when prompted, or run everything manually:
```bash title="Terminal"
make format
```
-Run `make hooks` once after cloning to install the pre-commit hooks that enforce this
-automatically at commit time.
+Run `make hooks` once after cloning to install the pre-commit hooks that enforce this automatically at commit time.
## Where to go next
- [Architecture](architecture) — what each ROS package does and how they fit together.
-- [Launching the Rover](launching) — the full build → CAN setup → launch workflow, including
- deploying to the onboard Orin.
+- [Launching the Rover](launching) — the full build → CAN setup → launch workflow, including deploying to the onboard Orin.
diff --git a/docs/launching.mdx b/docs/launching.mdx
index 847db4ac..eeb3ecda 100644
--- a/docs/launching.mdx
+++ b/docs/launching.mdx
@@ -7,7 +7,7 @@ This walks through the full workflow for getting Viator's software running end t
## Start mission control
-Mission control lives in its own repo, separate from `urc-2023`.
+Mission control lives in its own repo, separate from `viator`.
@@ -37,15 +37,15 @@ Mission control lives in its own repo, separate from `urc-2023`.
- Mission control is a plain Node/Vite project - run it on your host, not inside the `urc-2023`
- dev container.
+ Mission control is a plain Node/Vite project - run it on your host, not inside the `viator` dev
+ container.
## Connect to the rover
```bash title="Terminal"
ssh trickfire@192.168.0.112
-cd ~/urc-2023
+cd ~/viator
```
## Bring up the CAN bus
@@ -68,7 +68,7 @@ Back in the first terminal, bring the CAN interface up:
make can-setup
```
-This loads the `can`/`can_raw`/`mttcan` kernel modules, brings `can1` up at a 1 Mbit bitrate, and sends enable + speed-mode commands to the drivebase motors (CAN IDs `0x155`-`0x15A`). You should see that traffic show up in the `candump` terminal.
+This loads the `can`/`can_raw`/`mttcan` kernel modules, brings `can0` up at a 1 Mbit bitrate, and sends enable + speed-mode commands to the drivebase motors (CAN IDs `0x155`-`0x15A`). You should see that traffic show up in the `candump` terminal.
## Build and launch
diff --git a/scripts/build.sh b/scripts/build.sh
index d2942208..148fc8d7 100755
--- a/scripts/build.sh
+++ b/scripts/build.sh
@@ -1,8 +1,10 @@
#!/usr/bin/env bash
+cd "$(dirname "$0")/.."
+
source /opt/ros/$ROS_DISTRO/setup.bash
colcon build \
--symlink-install \
- --base-paths /home/trickfire/urc-2023 --cmake-args \
+ --base-paths . --cmake-args \
-DCMAKE_BUILD_TYPE=Debug
diff --git a/scripts/launch.sh b/scripts/launch.sh
index 0aa2012c..5d12e344 100755
--- a/scripts/launch.sh
+++ b/scripts/launch.sh
@@ -1,14 +1,13 @@
#!/usr/bin/env bash
+cd "$(dirname "$0")/.."
-source /opt/ros/$ROS_DISTRO/setup.bash
-source /home/trickfire/urc-2023/install/setup.bash
-
-#modprobe can
-#modprobe can_raw
-#modprobe mttcan
-#ip link set can0 type can bitrate 1000000 dbitrate 5000000 fd on
-#ip link set can0 up
+# enable colored logs
+export RCUTILS_COLORIZED_OUTPUT=1
+export PYTHONPATH="$(pwd)/src/:$PYTHONPATH"
-export PYTHONPATH="/home/trickfire/urc-2023/src/:$PYTHONPATH"
+# source ros
+source /opt/ros/$ROS_DISTRO/setup.bash
+source ./install/setup.bash
-ros2 launch viator_launch robot.launch.py --log-level rosbridge_websocket:=warn
+# launch using ros
+ros2 launch viator_launch robot.launch.py
diff --git a/scripts/setup-can-network.sh b/scripts/setup-can-network.sh
index 5cb76709..e863add2 100755
--- a/scripts/setup-can-network.sh
+++ b/scripts/setup-can-network.sh
@@ -1,20 +1,35 @@
#!/bin/bash
+set -e
+
+IFACE="${CAN_IFACE:-can0}"
+BITRATE=1000000
# Commands
START_CMD="8800000000000000"
CLEAR_CMD="9B00000000000000"
SPEED_CMD="A200000000000000"
+can_state() {
+ ip -details link show "$IFACE" | awk '/berr-counter/ {for (i = 1; i <= NF; i++) if ($i == "state") print $(i + 1)}'
+}
+
+tx_packets() {
+ ip -s link show "$IFACE" | awk '/^ *TX:/ {getline; print $2}'
+}
+
# Ensure driver dependencies are loaded
sudo modprobe can
sudo modprobe can_raw
sudo modprobe mttcan
# Set up the CAN interface
-sudo ip link set can1 down
-sudo ip link set can1 type can bitrate 1000000
-sudo ip link set can1 up
-echo "CAN interface can1 set up successfully."
+sudo ip link set "$IFACE" down
+sudo ip link set "$IFACE" type can bitrate "$BITRATE"
+sudo ip link set "$IFACE" up
+echo "CAN interface $IFACE set up successfully."
+
+TX_BEFORE=$(tx_packets)
+TX_BEFORE=${TX_BEFORE:-0}
# Motor CAN IDs (hexadecimal)
MOTOR_IDS=("155" "156" "157" "158" "159" "15A")
@@ -22,16 +37,31 @@ MOTOR_IDS=("155" "156" "157" "158" "159" "15A")
# Enable motors in speed mode
for CAN_ID in "${MOTOR_IDS[@]}"; do
echo "Sending clear command to CAN ID 0x$CAN_ID: $CLEAR_CMD"
- sudo cansend can1 "$CAN_ID#$CLEAR_CMD"
+ sudo cansend "$IFACE" "$CAN_ID#$CLEAR_CMD"
sleep 0.1
echo "Sending start command to CAN ID 0x$CAN_ID: $START_CMD"
- sudo cansend can1 "$CAN_ID#$START_CMD"
+ sudo cansend "$IFACE" "$CAN_ID#$START_CMD"
sleep 0.1
echo "Sending speed mode command to CAN ID 0x$CAN_ID: $SPEED_CMD"
- sudo cansend can1 "$CAN_ID#$SPEED_CMD"
+ sudo cansend "$IFACE" "$CAN_ID#$SPEED_CMD"
sleep 0.1
done
+TX_AFTER=$(tx_packets)
+TX_AFTER=${TX_AFTER:-0}
+TX_SENT=$((TX_AFTER - TX_BEFORE))
+STATE=$(can_state)
+
+if [ "$STATE" = "BUS-OFF" ] || [ "$TX_SENT" -eq 0 ]; then
+ echo "ERROR: $IFACE transmitted $TX_SENT frames and is in state ${STATE:-UNKNOWN}." >&2
+ echo "Nothing reached the bus, so candump will show nothing." >&2
+ echo "Check transceiver power and its standby pin, 120 ohm termination, CANH/CANL" >&2
+ echo "orientation, and that the motors are powered and set to $BITRATE bit/s." >&2
+ echo "Details: ip -details -statistics link show $IFACE" >&2
+ exit 1
+fi
+
echo "Speed setup commands sent to CAN IDs 21-26 (hex 0x15-0x1A)."
+echo "$TX_SENT frames confirmed transmitted on $IFACE (state: $STATE)."
diff --git a/scripts/sync-to-orin.sh b/scripts/sync-to-orin.sh
index 90d34fdb..ce87dbb6 100755
--- a/scripts/sync-to-orin.sh
+++ b/scripts/sync-to-orin.sh
@@ -1,25 +1,15 @@
#!/bin/bash
-# Syncs the local urc-2023 repo to a remote orin over rsync.
-# Usage: ./sync-to-orin.sh
-#
-# ip - IP address of the remote host (e.g. 192.168.0.148)
-# remote_path - Absolute path on the remote (e.g. /home/trickfire/urc-2023)
+# Syncs the local viator repo to a remote orin over rsync.
-if [ -z "$1" ] || [ -z "$2" ]; then
- echo "Usage: $0 "
- echo " ip IP address of the orin"
- echo " remote_path Path on the orin to the repo to sync"
- exit 1
-fi
+REMOTE_IP="192.168.0.112"
-REMOTE_IP="$1"
-REMOTE_PATH="$2"
+REMOTE_PATH="${1:-/home/trickfire/viator}"
LOCAL_PATH="$(cd "$(dirname "$0")/.." && git rev-parse --show-toplevel)/"
echo "Syncing to trickfire@${REMOTE_IP}:${REMOTE_PATH} ..."
-rsync -avz --progress \
+rsync -avz --delete --progress \
--exclude='.git/' \
--exclude='build/' \
--exclude='install/' \
diff --git a/src/arm/package.xml b/src/arm/package.xml
index 97ba82af..52b6d663 100644
--- a/src/arm/package.xml
+++ b/src/arm/package.xml
@@ -3,17 +3,12 @@
arm
0.0.0
- TODO: Package description
- trickfire
- TODO: License declaration
+ Controls the rover arm's motors and operating mode
+ trickfire
+ Apache-2.0
custom_interfaces
- ament_copyright
- ament_flake8
- ament_pep257
- python3-pytest
-
ament_python
diff --git a/src/arm/setup.py b/src/arm/setup.py
index e475a248..121f0912 100644
--- a/src/arm/setup.py
+++ b/src/arm/setup.py
@@ -13,10 +13,9 @@
install_requires=["setuptools"],
zip_safe=True,
maintainer="trickfire",
- maintainer_email="vladimirkupryukhin@gmail.com",
- description="TODO: Package description",
- license="TODO: License declaration",
- tests_require=["pytest"],
+ maintainer_email="tfrbtcs@uw.edu",
+ description="Controls the rover arm's motors and operating mode",
+ license="Apache-2.0",
entry_points={
"console_scripts": ["arm = arm.arm:main"],
},
diff --git a/src/arm/test/test_copyright.py b/src/arm/test/test_copyright.py
deleted file mode 100644
index 60c2d1e6..00000000
--- a/src/arm/test/test_copyright.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright 2015 Open Source Robotics Foundation, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import pytest
-from ament_copyright.main import main
-
-
-# Remove the `skip` decorator once the source file(s) have a copyright header
-@pytest.mark.skip(reason="No copyright header has been placed in the generated source file.")
-@pytest.mark.copyright
-@pytest.mark.linter
-def test_copyright():
- rc = main(argv=[".", "test"])
- assert rc == 0, "Found errors"
diff --git a/src/camera/package.xml b/src/camera/package.xml
index 2500f65e..8aa564e3 100644
--- a/src/camera/package.xml
+++ b/src/camera/package.xml
@@ -3,16 +3,15 @@
camera
0.0.0
- TODO: Package description
- trickfire
- TODO: License declaration
+ Captures and publishes compressed video from the rover's cameras
+ trickfire
+ Apache-2.0
- ament_copyright
- ament_flake8
- ament_pep257
- python3-pytest
+ rclpy
+ cv_bridge
+ sensor_msgs
ament_python
-
\ No newline at end of file
+
diff --git a/src/camera/setup.py b/src/camera/setup.py
index 805334a7..e34cdd21 100644
--- a/src/camera/setup.py
+++ b/src/camera/setup.py
@@ -13,10 +13,9 @@
install_requires=["setuptools"],
zip_safe=True,
maintainer="trickfire",
- maintainer_email="kimdavid2222@gmail.com",
- description="TODO: Package description",
- license="TODO: License declaration",
- tests_require=["pytest"],
+ maintainer_email="tfrbtcs@uw.edu",
+ description="Captures and publishes compressed video from the rover's cameras",
+ license="Apache-2.0",
entry_points={
"console_scripts": ["roscamera = camera.roscamera:main"],
},
diff --git a/src/camera/test/test_copyright.py b/src/camera/test/test_copyright.py
deleted file mode 100644
index 60c2d1e6..00000000
--- a/src/camera/test/test_copyright.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright 2015 Open Source Robotics Foundation, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import pytest
-from ament_copyright.main import main
-
-
-# Remove the `skip` decorator once the source file(s) have a copyright header
-@pytest.mark.skip(reason="No copyright header has been placed in the generated source file.")
-@pytest.mark.copyright
-@pytest.mark.linter
-def test_copyright():
- rc = main(argv=[".", "test"])
- assert rc == 0, "Found errors"
diff --git a/src/can_moteus/package.xml b/src/can_moteus/package.xml
index 025f5ab9..bf56641f 100644
--- a/src/can_moteus/package.xml
+++ b/src/can_moteus/package.xml
@@ -3,14 +3,10 @@
can_moteus
0.0.0
- TODO: Package description
- trickfire
- TODO: License declaration
+ Controls Moteus motor controllers over CAN
+ trickfire
+ Apache-2.0
- ament_copyright
- ament_flake8
- ament_pep257
- python3-pytest
rclpy
diff --git a/src/can_moteus/setup.py b/src/can_moteus/setup.py
index 38aceb45..804991d9 100644
--- a/src/can_moteus/setup.py
+++ b/src/can_moteus/setup.py
@@ -17,10 +17,9 @@
install_requires=["setuptools"],
zip_safe=True,
maintainer="trickfire",
- maintainer_email="trickfire@todo.todo",
- description="TODO: Package description",
- license="TODO: License declaration",
- tests_require=["pytest"],
+ maintainer_email="tfrbtcs@uw.edu",
+ description="Controls Moteus motor controllers over CAN",
+ license="Apache-2.0",
entry_points={
"console_scripts": ["can_moteus = can_moteus.ros_moteus_bridge:main"],
},
diff --git a/src/can_moteus/test/test_copyright.py b/src/can_moteus/test/test_copyright.py
deleted file mode 100644
index 60c2d1e6..00000000
--- a/src/can_moteus/test/test_copyright.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright 2015 Open Source Robotics Foundation, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import pytest
-from ament_copyright.main import main
-
-
-# Remove the `skip` decorator once the source file(s) have a copyright header
-@pytest.mark.skip(reason="No copyright header has been placed in the generated source file.")
-@pytest.mark.copyright
-@pytest.mark.linter
-def test_copyright():
- rc = main(argv=[".", "test"])
- assert rc == 0, "Found errors"
diff --git a/src/can_rmdx8/can_rmdx8/rmdx8_motor_manager.py b/src/can_rmdx8/can_rmdx8/rmdx8_motor_manager.py
index 76d087f6..acf28fc6 100644
--- a/src/can_rmdx8/can_rmdx8/rmdx8_motor_manager.py
+++ b/src/can_rmdx8/can_rmdx8/rmdx8_motor_manager.py
@@ -29,7 +29,7 @@ def __init__(self) -> None:
super().__init__("can_rmdx8_node")
self.get_logger().info(colorStr("Launching can_rmdx8 node", ColorCodes.BLUE_OK))
self._id_to_rmdx8_motor: dict[int, RMDx8Motor] = {}
- self.driver = rmd.CanDriver("can1")
+ self.driver = rmd.CanDriver("can0")
self._driver_lock = Lock()
self._req_buffer: deque[tuple[int, String]] = deque(maxlen=1000)
self._buffer_lock = Lock()
diff --git a/src/can_rmdx8/package.xml b/src/can_rmdx8/package.xml
index 25165770..c5234849 100644
--- a/src/can_rmdx8/package.xml
+++ b/src/can_rmdx8/package.xml
@@ -3,14 +3,9 @@
can_rmdx8
0.0.0
- TODO: Package description
- trickfire
- TODO: License declaration
-
- ament_copyright
- ament_flake8
- ament_pep257
- python3-pytest
+ Controls RMDx8 motors over CAN
+ trickfire
+ Apache-2.0
ament_python
diff --git a/src/can_rmdx8/setup.py b/src/can_rmdx8/setup.py
index 7aa0601d..dffeb7aa 100644
--- a/src/can_rmdx8/setup.py
+++ b/src/can_rmdx8/setup.py
@@ -13,10 +13,9 @@
install_requires=["setuptools"],
zip_safe=True,
maintainer="trickfire",
- maintainer_email="trickfire@todo.todo",
- description="TODO: Package description",
- license="TODO: License declaration",
- tests_require=["pytest"],
+ maintainer_email="tfrbtcs@uw.edu",
+ description="Controls RMDx8 motors over CAN",
+ license="Apache-2.0",
entry_points={
"console_scripts": ["can_rmdx8 = can_rmdx8.rmdx8_motor_manager:main"],
},
diff --git a/src/can_rmdx8/test/test_copyright.py b/src/can_rmdx8/test/test_copyright.py
deleted file mode 100644
index 60c2d1e6..00000000
--- a/src/can_rmdx8/test/test_copyright.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright 2015 Open Source Robotics Foundation, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import pytest
-from ament_copyright.main import main
-
-
-# Remove the `skip` decorator once the source file(s) have a copyright header
-@pytest.mark.skip(reason="No copyright header has been placed in the generated source file.")
-@pytest.mark.copyright
-@pytest.mark.linter
-def test_copyright():
- rc = main(argv=[".", "test"])
- assert rc == 0, "Found errors"
diff --git a/src/custom_interfaces/package.xml b/src/custom_interfaces/package.xml
index 53deff37..6a828636 100644
--- a/src/custom_interfaces/package.xml
+++ b/src/custom_interfaces/package.xml
@@ -3,9 +3,9 @@
custom_interfaces
0.0.0
- TODO: Package description
- trickfire
- TODO: License declaration
+ Custom ROS message and service definitions for Viator
+ trickfire
+ Apache-2.0
ament_cmake
diff --git a/src/drivebase/package.xml b/src/drivebase/package.xml
index 474fac57..dd4b1322 100644
--- a/src/drivebase/package.xml
+++ b/src/drivebase/package.xml
@@ -4,13 +4,8 @@
drivebase
0.0.0
Connects the controller to the wheel motors
- trickfire
- TODO: License declaration
-
- ament_copyright
- ament_flake8
- ament_pep257
- python3-pytest
+ trickfire
+ Apache-2.0
ament_python
diff --git a/src/drivebase/setup.py b/src/drivebase/setup.py
index 36d76aa0..dc40b522 100644
--- a/src/drivebase/setup.py
+++ b/src/drivebase/setup.py
@@ -13,10 +13,9 @@
install_requires=["setuptools"],
zip_safe=True,
maintainer="trickfire",
- maintainer_email="cklay@uw.edu",
+ maintainer_email="tfrbtcs@uw.edu",
description="Connects the controller to the wheel motors",
- license="TODO: License declaration",
- tests_require=["pytest"],
+ license="Apache-2.0",
entry_points={
"console_scripts": ["drivebase = drivebase.drivebase:main"],
},
diff --git a/src/drivebase/test/test_copyright.py b/src/drivebase/test/test_copyright.py
deleted file mode 100644
index 9167f3d7..00000000
--- a/src/drivebase/test/test_copyright.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright 2015 Open Source Robotics Foundation, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import pytest
-from ament_copyright.main import main
-
-
-@pytest.mark.copyright
-@pytest.mark.linter
-def test_copyright():
- rc = main(argv=[".", "test"])
- assert rc == 0, "Found errors"
diff --git a/src/heartbeat/heartbeat/heartbeat.py b/src/heartbeat/heartbeat/heartbeat.py
index 76c6afdc..b394246f 100644
--- a/src/heartbeat/heartbeat/heartbeat.py
+++ b/src/heartbeat/heartbeat/heartbeat.py
@@ -41,8 +41,8 @@ def __init__(self) -> None:
# give enough time (10s) for others to initialize
time.sleep(10)
- # flag to store connection status
- self._connection_lost = False
+ # flag to store connection status; starts "lost" until the first heartbeat arrives
+ self._connection_lost = True
# create subscription to mission control
self._is_alive_subscriber = self.create_subscription(
@@ -81,12 +81,17 @@ def heartbeat_callback(self, msg: Bool) -> None:
# Update the timestamp of the last received heartbeat message
self._last_heartbeat_time = time.time()
- # Log connection active as before
# doesn't matter the data, pub always pub True
# just check to make sure nothing is wrong with pub
if msg.data:
- self.get_logger().info(colorStr("Connection active", ColorCodes.GREEN_OK))
- self._connection_lost = False
+ # Only log at INFO on the transition into a connected state (startup or
+ # reconnect); the recurring per-second tick goes to DEBUG so it doesn't
+ # flood the default INFO output.
+ if self._connection_lost:
+ self.get_logger().info(colorStr("Connection active", ColorCodes.GREEN_OK))
+ self._connection_lost = False
+ else:
+ self.get_logger().debug(colorStr("Connection active", ColorCodes.GREEN_OK))
# Tell the client that the heartbeat was received.
msg = Bool()
diff --git a/src/heartbeat/package.xml b/src/heartbeat/package.xml
index d2ba95be..8e95d55a 100644
--- a/src/heartbeat/package.xml
+++ b/src/heartbeat/package.xml
@@ -3,18 +3,13 @@
heartbeat
0.0.0
- Heartbeat Node Package
- trickfire
- TODO: License declaration
+ Monitors rover connectivity and stops the motors if it's lost
+ trickfire
+ Apache-2.0
rclpy
std_msgs
- ament_copyright
- ament_flake8
- ament_pep257
- python3-pytest
-
ament_python
diff --git a/src/heartbeat/setup.py b/src/heartbeat/setup.py
index f745ee2a..fc205620 100644
--- a/src/heartbeat/setup.py
+++ b/src/heartbeat/setup.py
@@ -13,10 +13,9 @@
install_requires=["setuptools"],
zip_safe=True,
maintainer="trickfire",
- maintainer_email="vanillanguyen635@gmail.com",
- description="TODO: Package description",
- license="TODO: License declaration",
- tests_require=["pytest"],
+ maintainer_email="tfrbtcs@uw.edu",
+ description="Monitors rover connectivity and stops the motors if it's lost",
+ license="Apache-2.0",
entry_points={
"console_scripts": [
# ros 2 executable = packagename.filename : function we want to run
diff --git a/src/heartbeat/test/test_copyright.py b/src/heartbeat/test/test_copyright.py
deleted file mode 100644
index 60c2d1e6..00000000
--- a/src/heartbeat/test/test_copyright.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright 2015 Open Source Robotics Foundation, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import pytest
-from ament_copyright.main import main
-
-
-# Remove the `skip` decorator once the source file(s) have a copyright header
-@pytest.mark.skip(reason="No copyright header has been placed in the generated source file.")
-@pytest.mark.copyright
-@pytest.mark.linter
-def test_copyright():
- rc = main(argv=[".", "test"])
- assert rc == 0, "Found errors"
diff --git a/src/heartbeat/test/test_flake8.py b/src/heartbeat/test/test_flake8.py
deleted file mode 100644
index 22fffcb8..00000000
--- a/src/heartbeat/test/test_flake8.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright 2017 Open Source Robotics Foundation, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import pytest
-from ament_flake8.main import main_with_errors
-
-
-@pytest.mark.flake8
-@pytest.mark.linter
-def test_flake8():
- rc, errors = main_with_errors(argv=[])
- assert rc == 0, "Found %d code style errors / warnings:\n" % len(errors) + "\n".join(errors)
diff --git a/src/heartbeat/test/test_pep257.py b/src/heartbeat/test/test_pep257.py
deleted file mode 100644
index 4eddb46e..00000000
--- a/src/heartbeat/test/test_pep257.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright 2015 Open Source Robotics Foundation, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import pytest
-from ament_pep257.main import main
-
-
-@pytest.mark.linter
-@pytest.mark.pep257
-def test_pep257():
- rc = main(argv=[".", "test"])
- assert rc == 0, "Found code style errors / warnings"
diff --git a/src/mission_control_updater/package.xml b/src/mission_control_updater/package.xml
index fb8ad91e..d45a70ab 100644
--- a/src/mission_control_updater/package.xml
+++ b/src/mission_control_updater/package.xml
@@ -3,14 +3,9 @@
mission_control_updater
0.0.0
- TODO: Package description
- trickfire
- TODO: License declaration
-
- ament_copyright
- ament_flake8
- ament_pep257
- python3-pytest
+ Sends rover telemetry to Mission Control
+ trickfire
+ Apache-2.0
ament_python
diff --git a/src/mission_control_updater/setup.py b/src/mission_control_updater/setup.py
index f6469a61..629cec5b 100644
--- a/src/mission_control_updater/setup.py
+++ b/src/mission_control_updater/setup.py
@@ -13,10 +13,9 @@
install_requires=["setuptools"],
zip_safe=True,
maintainer="trickfire",
- maintainer_email="vladimirkupryukhin@gmail.com",
- description="TODO: Package description",
- license="TODO: License declaration",
- tests_require=["pytest"],
+ maintainer_email="tfrbtcs@uw.edu",
+ description="Sends rover telemetry to Mission Control",
+ license="Apache-2.0",
entry_points={
"console_scripts": ["mission_control_updater = mission_control_updater.updater:main"],
},
diff --git a/src/mission_control_updater/test/test_copyright.py b/src/mission_control_updater/test/test_copyright.py
deleted file mode 100644
index 60c2d1e6..00000000
--- a/src/mission_control_updater/test/test_copyright.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright 2015 Open Source Robotics Foundation, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import pytest
-from ament_copyright.main import main
-
-
-# Remove the `skip` decorator once the source file(s) have a copyright header
-@pytest.mark.skip(reason="No copyright header has been placed in the generated source file.")
-@pytest.mark.copyright
-@pytest.mark.linter
-def test_copyright():
- rc = main(argv=[".", "test"])
- assert rc == 0, "Found errors"
diff --git a/src/viator_launch/launch/robot.launch.py b/src/viator_launch/launch/robot.launch.py
index 62e2d674..017b0ace 100644
--- a/src/viator_launch/launch/robot.launch.py
+++ b/src/viator_launch/launch/robot.launch.py
@@ -7,18 +7,13 @@
from launch_xml.launch_description_sources import XMLLaunchDescriptionSource
can_moteus_node = Node(package="can_moteus", executable="can_moteus", name="can_moteus_node")
-
-
drivebase_node = Node(package="drivebase", executable="drivebase", name="drivebase_node")
-# Runs as root via sudo: opening the raw CAN socket for can1 needs CAP_NET_RAW/NET_ADMIN,
-# which the non-root trickfire user doesn't have (see .devcontainer/trickfire-can-sudoers).
-can_rmdx8_node = Node(
- package="can_rmdx8",
- executable="can_rmdx8",
- name="can_rmdx8_node",
- prefix="sudo -n --",
-)
+# must stay non-root like every other node here: FastDDS falls back to shared memory for
+# same-host traffic and those /dev/shm segments are 0644, so a root node and a trickfire
+# node discover each other but silently exchange no data. AF_CAN raw sockets don't need
+# CAP_NET_RAW anyway (unlike AF_INET), only bringing the link up does
+can_rmdx8_node = Node(package="can_rmdx8", executable="can_rmdx8", name="can_rmdx8_node")
mission_control_updater_node = Node(
package="mission_control_updater",
@@ -54,7 +49,7 @@
def generate_launch_description() -> launch.LaunchDescription: # pylint: disable=invalid-name
return launch.LaunchDescription(
[
- can_moteus_node,
+ # can_moteus_node, (dsabeled for now cause arm is not implemented)
drivebase_node,
can_rmdx8_node,
mission_control_updater_node,
diff --git a/src/viator_launch/package.xml b/src/viator_launch/package.xml
index 2a692421..30107fd0 100644
--- a/src/viator_launch/package.xml
+++ b/src/viator_launch/package.xml
@@ -3,9 +3,9 @@
viator_launch
0.0.0
- TODO: Package description
- trickfire
- TODO: License declaration
+ Launch files for starting the Viator rover
+ trickfire
+ Apache-2.0
can_moteus
can_rmdx8
@@ -13,13 +13,6 @@
mission_control_updater
arm
camera
- example_node
-
-
- ament_copyright
- ament_flake8
- ament_pep257
- python3-pytest
ament_python
diff --git a/src/viator_launch/setup.py b/src/viator_launch/setup.py
index 070aeb3b..ee0f2bf4 100644
--- a/src/viator_launch/setup.py
+++ b/src/viator_launch/setup.py
@@ -18,8 +18,7 @@
# Zip-safety is not yet confirmed.
zip_safe=True,
maintainer="trickfire",
- maintainer_email="phillipov@outlook.com",
- description="TODO: Package description",
- license="TODO: License declaration",
- tests_require=["pytest"],
+ maintainer_email="tfrbtcs@uw.edu",
+ description="Launch files for starting the Viator rover",
+ license="Apache-2.0",
)
diff --git a/src/viator_launch/test/test_copyright.py b/src/viator_launch/test/test_copyright.py
deleted file mode 100644
index 9167f3d7..00000000
--- a/src/viator_launch/test/test_copyright.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright 2015 Open Source Robotics Foundation, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import pytest
-from ament_copyright.main import main
-
-
-@pytest.mark.copyright
-@pytest.mark.linter
-def test_copyright():
- rc = main(argv=[".", "test"])
- assert rc == 0, "Found errors"