From 24dce006b6dc65757c0e07ea9a0a62d70692885e Mon Sep 17 00:00:00 2001 From: Mohammad Durrani Date: Thu, 29 Jan 2026 15:31:29 -0500 Subject: [PATCH 1/3] added initial setup --- src/tools/scripts/can_setup.sh | 5 - src/tools/scripts/framework_network_setup.sh | 6 + src/tools/scripts/jetson_setup/can-setup.sh | 17 ++ src/tools/scripts/jetson_setup/can.service | 14 ++ .../scripts/jetson_setup/canable-setup.sh | 20 +++ .../scripts/jetson_setup/jetson_setup.sh | 168 ++++++++++++++++++ src/tools/scripts/rover_tmux_dev_env_setup.sh | 13 ++ 7 files changed, 238 insertions(+), 5 deletions(-) delete mode 100755 src/tools/scripts/can_setup.sh create mode 100644 src/tools/scripts/framework_network_setup.sh create mode 100755 src/tools/scripts/jetson_setup/can-setup.sh create mode 100644 src/tools/scripts/jetson_setup/can.service create mode 100755 src/tools/scripts/jetson_setup/canable-setup.sh create mode 100755 src/tools/scripts/jetson_setup/jetson_setup.sh create mode 100644 src/tools/scripts/rover_tmux_dev_env_setup.sh diff --git a/src/tools/scripts/can_setup.sh b/src/tools/scripts/can_setup.sh deleted file mode 100755 index f2dd043..0000000 --- a/src/tools/scripts/can_setup.sh +++ /dev/null @@ -1,5 +0,0 @@ -sudo killall slcand -sudo slcand -o -c -s8 /dev/ttyACM0 can0 -sudo slcand -o -c -s8 /dev/ttyACM1 can0 -sudo ip link set can0 up type can bitrate 1000000 -sudo ifconfig can0 txqueuelen 1000 \ No newline at end of file diff --git a/src/tools/scripts/framework_network_setup.sh b/src/tools/scripts/framework_network_setup.sh new file mode 100644 index 0000000..e623860 --- /dev/null +++ b/src/tools/scripts/framework_network_setup.sh @@ -0,0 +1,6 @@ +sudo ip addr add 192.168.1.2/24 dev enx9cbf0d007947 +sudo ip route del 10.42.0.0/24 dev enx9cbf0d007947 +sudo ip route del 169.254.0.0/16 dev enx9cbf0d007947 +sudo ip route add 192.168.1.0/24 dev enx9cbf0d007947 src 192.168.1.2 +sudo ip addr del 10.42.0.1/24 dev enx9cbf0d007947 +ip route diff --git a/src/tools/scripts/jetson_setup/can-setup.sh b/src/tools/scripts/jetson_setup/can-setup.sh new file mode 100755 index 0000000..0a59d85 --- /dev/null +++ b/src/tools/scripts/jetson_setup/can-setup.sh @@ -0,0 +1,17 @@ +#!/bin/bash +# SPECIFICALLY for orin nx, pinmux wrong for other devices +set -euo pipefail + +# load can kernel modules +modprobe can +modprobe can_raw +modprobe mttcan + +# https://docs.nvidia.com/jetson/archives/r35.3.1/DeveloperGuide/text/HR/ControllerAreaNetworkCan.html#jetson-platform-details +busybox devmem 0x0c303018 w 0xc458 # can0_din +busybox devmem 0x0c303010 w 0xc400 # can0_dout + +ip link set can0 up type can \ + bitrate 1000000 \ + berr-reporting on \ + restart-ms 1000 diff --git a/src/tools/scripts/jetson_setup/can.service b/src/tools/scripts/jetson_setup/can.service new file mode 100644 index 0000000..313f15d --- /dev/null +++ b/src/tools/scripts/jetson_setup/can.service @@ -0,0 +1,14 @@ +[Unit] +Description=CAN Interface Setup +After=network.target +Wants=network.target + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/can-setup.sh +RemainAfterExit=yes +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target diff --git a/src/tools/scripts/jetson_setup/canable-setup.sh b/src/tools/scripts/jetson_setup/canable-setup.sh new file mode 100755 index 0000000..64e38a9 --- /dev/null +++ b/src/tools/scripts/jetson_setup/canable-setup.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +set -euo pipefail + +# kill existing processes +killall slcand 2>/dev/null || true +sleep 1 + +# start slcand +if [[ -e /dev/ttyACM0 ]]; then + slcand -o -c -s8 /dev/ttyACM0 can0 +elif [[ -e /dev/ttyACM1 ]]; then + slcand -o -c -s8 /dev/ttyACM1 can0 +else + echo "No CANable device found on /dev/ttyACM0 or /dev/ttyACM1" + exit 1 +fi + +ip link set can0 up +ip link set can0 txqueuelen 1000 diff --git a/src/tools/scripts/jetson_setup/jetson_setup.sh b/src/tools/scripts/jetson_setup/jetson_setup.sh new file mode 100755 index 0000000..1e22854 --- /dev/null +++ b/src/tools/scripts/jetson_setup/jetson_setup.sh @@ -0,0 +1,168 @@ +#!/bin/bash +set -euo pipefail + +if [[ $EUID -ne 0 ]]; then + echo "[ERROR] This script must be run as root (use sudo)" + exit 1 +fi + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ATHENA_REPO_DIR="${HOME}/athena-code" +ATHENA_REPO_URL="https://github.com/umdloop/athena-code.git" + +install_ros2_humble() { + echo "[INFO] Installing ROS2 Humble Hawksbill..." + + if [[ -f /opt/ros/humble/setup.bash ]]; then + echo "[WARN] ROS2 Humble already installed, skipping..." + return 0 + fi + + apt-get update && apt-get install -y locales + locale-gen en_US en_US.UTF-8 + update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 + export LANG=en_US.UTF-8 + + apt-get install -y software-properties-common curl + add-apt-repository -y universe + curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg + echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | tee /etc/apt/sources.list.d/ros2.list > /dev/null + + apt-get update + apt-get install -y ros-humble-desktop ros-dev-tools + + echo "[INFO] ROS2 Humble installed successfully" +} + +setup_athena_code() { + echo "[INFO] Setting up athena-code repository..." + + if [[ ! -d "$ATHENA_REPO_DIR" ]]; then + echo "[INFO] Cloning athena-code repository..." + sudo -u $SUDO_USER git clone "$ATHENA_REPO_URL" "$ATHENA_REPO_DIR" + else + echo "[WARN] athena-code directory already exists, skipping clone..." + fi + + cd "$ATHENA_REPO_DIR" + bash dependencies.sh + + echo "[INFO] Building athena-code workspace..." + source /opt/ros/humble/setup.bash + sudo -u $SUDO_USER bash -c "source /opt/ros/humble/setup.bash && cd $ATHENA_REPO_DIR && colcon build --symlink-install" + + echo "[INFO] athena-code built successfully" +} + +configure_can() { + echo "[INFO] Configuring CAN interface..." + + echo "Select CAN interface type:" + echo "1) Native Jetson CAN (can0/mttcan)" + echo "2) CANable USB adapter (slcand)" + read -p "Enter choice [1-2]: " can_choice + + case $can_choice in + 1) configure_native_can ;; + 2) configure_canable ;; + *) + echo "[ERROR] Invalid choice" + exit 1 + ;; + esac +} + +setup_can_common() { + local setup_script=$1 + local packages=$2 + + apt-get install -y $packages + cp "${SCRIPT_DIR}/${setup_script}" /usr/local/bin/can-setup.sh + chmod +x /usr/local/bin/can-setup.sh + cp "${SCRIPT_DIR}/can.service" /etc/systemd/system/can.service + setup_can_service +} + +configure_native_can() { + echo "[INFO] Configuring native Jetson CAN interface..." + setup_can_common "can-setup.sh" "can-utils busybox" +} + +configure_canable() { + echo "[INFO] Configuring CANable USB adapter..." + setup_can_common "canable-setup.sh" "can-utils" +} + +setup_can_service() { + echo "[INFO] Setting up CAN systemd service..." + + if systemctl is-enabled can.service &>/dev/null; then + echo "[WARN] CAN service already enabled" + systemctl restart can.service + else + systemctl daemon-reload + systemctl enable can.service + systemctl start can.service + fi + + echo "[INFO] CAN service installed and enabled" +} + +configure_networking() { + echo "[INFO] Configuring network routes for radios..." + + echo "Available network interfaces:" + ip link show | grep -E '^[0-9]+:' | awk -F': ' '{print $2}' | grep -v lo + + read -p "Enter the network interface name or press Enter to skip: " NETWORK_INTERFACE + + if [[ -z "$NETWORK_INTERFACE" ]]; then + echo "[WARN] Skipping network configuration" + return 0 + fi + + read -p "Enter the IP address to assign: " NETWORK_IP + + if [[ -z "$NETWORK_IP" ]]; then + echo "[WARN] No IP provided, skipping network configuration" + return 0 + fi + + local conn_name="athena-radio" + + nmcli connection delete "$conn_name" 2>/dev/null || true + + nmcli connection add type ethernet \ + con-name "$conn_name" \ + ifname "$NETWORK_INTERFACE" \ + ipv4.method manual \ + ipv4.addresses "${NETWORK_IP}/24" \ + connection.autoconnect yes + + nmcli connection up "$conn_name" + + echo "[INFO] Network configuration completed for $NETWORK_INTERFACE" +} + +main() { + echo "[INFO] Starting Jetson setup for athena-code..." + echo + + install_ros2_humble + echo + + setup_athena_code + echo + + configure_can + echo + + configure_networking + echo + + echo "[INFO] Setup complete!" + echo "[INFO] Please reboot the system to ensure all changes take effect." + echo "[INFO] After reboot, source the workspace: source ${ATHENA_REPO_DIR}/install/setup.bash" +} + +main diff --git a/src/tools/scripts/rover_tmux_dev_env_setup.sh b/src/tools/scripts/rover_tmux_dev_env_setup.sh new file mode 100644 index 0000000..2a8ba93 --- /dev/null +++ b/src/tools/scripts/rover_tmux_dev_env_setup.sh @@ -0,0 +1,13 @@ +!#/bin/bash +SESSION="rover-dev" +WORKSPACE="$HOME/ROS/ros_dev_ws" + +tmux new-session -d -s $SESSION -c $WORKSPACE + +# Pane 0: Neovim for code editing +tmux rename-window -t $SESSION:0 'Code' +tmux send-keys -t $SESSION:0 'nvim .' C-m + + +# Pane 1: Build monitor +tmux new-window From 1c5291882cf909a2708f14a960a3570d27bf0398 Mon Sep 17 00:00:00 2001 From: Mohammad Durrani Date: Sun, 1 Feb 2026 11:40:13 -0500 Subject: [PATCH 2/3] configured the setup script --- src/tools/scripts/framework_network_setup.sh | 5 - .../{can.service => umdloop_can.service} | 8 +- .../{can-setup.sh => umdloop_can_setup.sh} | 0 ...able-setup.sh => umdloop_canable_setup.sh} | 2 - ...etson_setup.sh => umdloop_jetson_setup.sh} | 92 ++++++++++++------- src/tools/scripts/rover_tmux_dev_env_setup.sh | 13 --- 6 files changed, 61 insertions(+), 59 deletions(-) rename src/tools/scripts/jetson_setup/{can.service => umdloop_can.service} (56%) mode change 100644 => 100755 rename src/tools/scripts/jetson_setup/{can-setup.sh => umdloop_can_setup.sh} (100%) rename src/tools/scripts/jetson_setup/{canable-setup.sh => umdloop_canable_setup.sh} (89%) rename src/tools/scripts/jetson_setup/{jetson_setup.sh => umdloop_jetson_setup.sh} (59%) delete mode 100644 src/tools/scripts/rover_tmux_dev_env_setup.sh diff --git a/src/tools/scripts/framework_network_setup.sh b/src/tools/scripts/framework_network_setup.sh index e623860..0784c65 100644 --- a/src/tools/scripts/framework_network_setup.sh +++ b/src/tools/scripts/framework_network_setup.sh @@ -1,6 +1 @@ sudo ip addr add 192.168.1.2/24 dev enx9cbf0d007947 -sudo ip route del 10.42.0.0/24 dev enx9cbf0d007947 -sudo ip route del 169.254.0.0/16 dev enx9cbf0d007947 -sudo ip route add 192.168.1.0/24 dev enx9cbf0d007947 src 192.168.1.2 -sudo ip addr del 10.42.0.1/24 dev enx9cbf0d007947 -ip route diff --git a/src/tools/scripts/jetson_setup/can.service b/src/tools/scripts/jetson_setup/umdloop_can.service old mode 100644 new mode 100755 similarity index 56% rename from src/tools/scripts/jetson_setup/can.service rename to src/tools/scripts/jetson_setup/umdloop_can.service index 313f15d..8e8fe38 --- a/src/tools/scripts/jetson_setup/can.service +++ b/src/tools/scripts/jetson_setup/umdloop_can.service @@ -1,14 +1,12 @@ [Unit] Description=CAN Interface Setup -After=network.target -Wants=network.target +After=systemd-modules-load.service [Service] Type=oneshot ExecStart=/usr/local/bin/can-setup.sh +ExecStop=/sbin/ip link set can0 down RemainAfterExit=yes -Restart=on-failure -RestartSec=5 [Install] -WantedBy=multi-user.target +WantedBy=multi-user.target \ No newline at end of file diff --git a/src/tools/scripts/jetson_setup/can-setup.sh b/src/tools/scripts/jetson_setup/umdloop_can_setup.sh similarity index 100% rename from src/tools/scripts/jetson_setup/can-setup.sh rename to src/tools/scripts/jetson_setup/umdloop_can_setup.sh diff --git a/src/tools/scripts/jetson_setup/canable-setup.sh b/src/tools/scripts/jetson_setup/umdloop_canable_setup.sh similarity index 89% rename from src/tools/scripts/jetson_setup/canable-setup.sh rename to src/tools/scripts/jetson_setup/umdloop_canable_setup.sh index 64e38a9..2cfc12a 100755 --- a/src/tools/scripts/jetson_setup/canable-setup.sh +++ b/src/tools/scripts/jetson_setup/umdloop_canable_setup.sh @@ -2,11 +2,9 @@ set -euo pipefail -# kill existing processes killall slcand 2>/dev/null || true sleep 1 -# start slcand if [[ -e /dev/ttyACM0 ]]; then slcand -o -c -s8 /dev/ttyACM0 can0 elif [[ -e /dev/ttyACM1 ]]; then diff --git a/src/tools/scripts/jetson_setup/jetson_setup.sh b/src/tools/scripts/jetson_setup/umdloop_jetson_setup.sh similarity index 59% rename from src/tools/scripts/jetson_setup/jetson_setup.sh rename to src/tools/scripts/jetson_setup/umdloop_jetson_setup.sh index 1e22854..540e2f9 100755 --- a/src/tools/scripts/jetson_setup/jetson_setup.sh +++ b/src/tools/scripts/jetson_setup/umdloop_jetson_setup.sh @@ -1,18 +1,29 @@ #!/bin/bash set -euo pipefail +trap 'echo "[ERROR] Script failed at line $LINENO"' ERR + if [[ $EUID -ne 0 ]]; then - echo "[ERROR] This script must be run as root (use sudo)" - exit 1 + echo "[ERROR] This script must be run as root (use sudo)" + exit 1 +fi + +if [[ -z "${SUDO_USER:-}" ]]; then + echo "[ERROR] Please run with sudo, not as root directly" + exit 1 fi SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -ATHENA_REPO_DIR="${HOME}/athena-code" +USER_HOME="$(getent passwd "$SUDO_USER" | cut -d: -f6)" +ATHENA_REPO_DIR="${USER_HOME}/athena-code" ATHENA_REPO_URL="https://github.com/umdloop/athena-code.git" install_ros2_humble() { echo "[INFO] Installing ROS2 Humble Hawksbill..." + echo "[INFO] Installing Git" + apt-get install -y git-all + if [[ -f /opt/ros/humble/setup.bash ]]; then echo "[WARN] ROS2 Humble already installed, skipping..." return 0 @@ -39,17 +50,23 @@ setup_athena_code() { if [[ ! -d "$ATHENA_REPO_DIR" ]]; then echo "[INFO] Cloning athena-code repository..." - sudo -u $SUDO_USER git clone "$ATHENA_REPO_URL" "$ATHENA_REPO_DIR" + sudo -u "$SUDO_USER" git clone "$ATHENA_REPO_URL" "$ATHENA_REPO_DIR" else echo "[WARN] athena-code directory already exists, skipping clone..." fi - cd "$ATHENA_REPO_DIR" + cd "$ATHENA_REPO_DIR" || { echo "[ERROR] Failed to cd to $ATHENA_REPO_DIR"; exit 1; } bash dependencies.sh echo "[INFO] Building athena-code workspace..." + + # Add to user's bashrc if not already present + if ! grep -qxF 'source /opt/ros/humble/setup.bash' "$USER_HOME/.bashrc"; then + echo 'source /opt/ros/humble/setup.bash' >> "$USER_HOME/.bashrc" + fi + source /opt/ros/humble/setup.bash - sudo -u $SUDO_USER bash -c "source /opt/ros/humble/setup.bash && cd $ATHENA_REPO_DIR && colcon build --symlink-install" + colcon build --symlink-install echo "[INFO] athena-code built successfully" } @@ -57,52 +74,57 @@ setup_athena_code() { configure_can() { echo "[INFO] Configuring CAN interface..." - echo "Select CAN interface type:" - echo "1) Native Jetson CAN (can0/mttcan)" - echo "2) CANable USB adapter (slcand)" - read -p "Enter choice [1-2]: " can_choice - - case $can_choice in - 1) configure_native_can ;; - 2) configure_canable ;; - *) - echo "[ERROR] Invalid choice" - exit 1 - ;; - esac + while true; do + echo "Select CAN interface type:" + echo "1) Native Jetson CAN (can0/mttcan)" + echo "2) CANable USB adapter (slcand)" + echo "3) Skip CAN configuration" + read -p "Enter choice [1-3]: " can_choice + + case $can_choice in + 1) configure_native_can; return ;; + 2) configure_canable; return ;; + 3) echo "[INFO] Skipping CAN configuration"; return ;; + *) + echo "[ERROR] Invalid choice. Please try again." + ;; + esac + done } setup_can_common() { local setup_script=$1 - local packages=$2 + shift + local packages=("$@") - apt-get install -y $packages - cp "${SCRIPT_DIR}/${setup_script}" /usr/local/bin/can-setup.sh - chmod +x /usr/local/bin/can-setup.sh - cp "${SCRIPT_DIR}/can.service" /etc/systemd/system/can.service + apt-get install -y "${packages[@]}" + cp "${SCRIPT_DIR}/${setup_script}" /usr/local/bin/umdloop_can_setup.sh + chmod +x /usr/local/bin/umdloop_can_setup.sh + cp "${SCRIPT_DIR}/umdloop_can.service" /etc/systemd/system/umdloop_can.service setup_can_service } configure_native_can() { echo "[INFO] Configuring native Jetson CAN interface..." - setup_can_common "can-setup.sh" "can-utils busybox" + setup_can_common "umdloop_can_setup.sh" "can-utils" "busybox" } configure_canable() { echo "[INFO] Configuring CANable USB adapter..." - setup_can_common "canable-setup.sh" "can-utils" + setup_can_common "umdloop_canable_setup.sh" "can-utils" } setup_can_service() { echo "[INFO] Setting up CAN systemd service..." - if systemctl is-enabled can.service &>/dev/null; then + if systemctl is-enabled umdloop_can.service &>/dev/null; then echo "[WARN] CAN service already enabled" - systemctl restart can.service + ip link set can0 down 2>/dev/null || true + systemctl restart umdloop_can.service else systemctl daemon-reload - systemctl enable can.service - systemctl start can.service + systemctl enable umdloop_can.service + systemctl start umdloop_can.service fi echo "[INFO] CAN service installed and enabled" @@ -121,13 +143,16 @@ configure_networking() { return 0 fi - read -p "Enter the IP address to assign: " NETWORK_IP + read -p "Enter the IP address to assign (e.g., 192.168.1.10): " NETWORK_IP if [[ -z "$NETWORK_IP" ]]; then echo "[WARN] No IP provided, skipping network configuration" return 0 fi + read -p "Enter subnet prefix length [24]: " SUBNET_PREFIX + SUBNET_PREFIX="${SUBNET_PREFIX:-24}" + local conn_name="athena-radio" nmcli connection delete "$conn_name" 2>/dev/null || true @@ -136,7 +161,7 @@ configure_networking() { con-name "$conn_name" \ ifname "$NETWORK_INTERFACE" \ ipv4.method manual \ - ipv4.addresses "${NETWORK_IP}/24" \ + ipv4.addresses "${NETWORK_IP}/${SUBNET_PREFIX}" \ connection.autoconnect yes nmcli connection up "$conn_name" @@ -162,7 +187,6 @@ main() { echo "[INFO] Setup complete!" echo "[INFO] Please reboot the system to ensure all changes take effect." - echo "[INFO] After reboot, source the workspace: source ${ATHENA_REPO_DIR}/install/setup.bash" } -main +main \ No newline at end of file diff --git a/src/tools/scripts/rover_tmux_dev_env_setup.sh b/src/tools/scripts/rover_tmux_dev_env_setup.sh deleted file mode 100644 index 2a8ba93..0000000 --- a/src/tools/scripts/rover_tmux_dev_env_setup.sh +++ /dev/null @@ -1,13 +0,0 @@ -!#/bin/bash -SESSION="rover-dev" -WORKSPACE="$HOME/ROS/ros_dev_ws" - -tmux new-session -d -s $SESSION -c $WORKSPACE - -# Pane 0: Neovim for code editing -tmux rename-window -t $SESSION:0 'Code' -tmux send-keys -t $SESSION:0 'nvim .' C-m - - -# Pane 1: Build monitor -tmux new-window From f375dbf15a6884d01230c78ac2fe415848ef4d49 Mon Sep 17 00:00:00 2001 From: Mohammad Durrani Date: Sun, 1 Feb 2026 11:41:10 -0500 Subject: [PATCH 3/3] add note --- src/tools/scripts/jetson_setup/umdloop_jetson_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/scripts/jetson_setup/umdloop_jetson_setup.sh b/src/tools/scripts/jetson_setup/umdloop_jetson_setup.sh index 540e2f9..471e43c 100755 --- a/src/tools/scripts/jetson_setup/umdloop_jetson_setup.sh +++ b/src/tools/scripts/jetson_setup/umdloop_jetson_setup.sh @@ -3,6 +3,7 @@ set -euo pipefail trap 'echo "[ERROR] Script failed at line $LINENO"' ERR +# having both of these are weird but they make sure you use sudo and you're not logged in as root (don't know the userdir if you're logged in as root) if [[ $EUID -ne 0 ]]; then echo "[ERROR] This script must be run as root (use sudo)" exit 1 @@ -60,7 +61,6 @@ setup_athena_code() { echo "[INFO] Building athena-code workspace..." - # Add to user's bashrc if not already present if ! grep -qxF 'source /opt/ros/humble/setup.bash' "$USER_HOME/.bashrc"; then echo 'source /opt/ros/humble/setup.bash' >> "$USER_HOME/.bashrc" fi