#!/usr/bin/env bash set -eo pipefail export DISPLAY="${DISPLAY:-:0}" export XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}" export DBUS_SESSION_BUS_ADDRESS="${DBUS_SESSION_BUS_ADDRESS:-unix:path=${XDG_RUNTIME_DIR}/bus}" repo_root="$HOME/go2_robot_system" runtime_env="$repo_root/scripts/go2_os_runtime.env" dashboard_env="$repo_root/go2_dashboard/config/dashboard.env" if [[ -f "$dashboard_env" ]]; then set -a # shellcheck disable=SC1090 source "$dashboard_env" set +a fi export GO2_OS_ROLE=dashboard unset GO2_OS_ROS_IFACE # Load local interface defaults without forcing DDS setup yet. The dashboard must # stay visible while the robot link is unplugged; motion remains blocked below. if [[ -f "$runtime_env" ]]; then # shellcheck disable=SC1090 source "$runtime_env" fi selected_ros_iface="${GO2_OS_DASHBOARD_IFACE:-${GO2_OS_NAV_IFACE:-${GO2_OS_WIRED_IFACE:-ens160}}}" iface_state="$(cat "/sys/class/net/${selected_ros_iface}/operstate" 2>/dev/null || true)" iface_carrier="$(cat "/sys/class/net/${selected_ros_iface}/carrier" 2>/dev/null || true)" iface_ipv4="$(ip -4 -o addr show dev "${selected_ros_iface}" 2>/dev/null | awk '{print $4}' | cut -d/ -f1 | head -n 1)" if [[ "${iface_state}" == "up" && "${iface_carrier:-1}" == "1" && -n "${iface_ipv4}" ]]; then # shellcheck disable=SC1091 source "$repo_root/scripts/go2_os_env.sh" else blocking_error="wired_required:${selected_ros_iface}:state=${iface_state:-unknown} carrier=${iface_carrier:-n/a} ipv4=${iface_ipv4:-none}" export GO2_OS_NETWORK_BLOCKING_ERROR="$blocking_error" export OPEN_SOURCE_DASHBOARD_NETWORK_BLOCKING_ERROR="$blocking_error" export OPEN_SOURCE_DASHBOARD_ROS_IFACE="$selected_ros_iface" export OPEN_SOURCE_DASHBOARD_NETWORK_SELECTED_IFACE="$selected_ros_iface" export GO2_OS_ROS_IFACE="$selected_ros_iface" export GO2_OS_TRANSPORT_POLICY="wired_required" export GO2_OS_SELECTED_IFACE_REASON="$blocking_error" export GO2_OS_FALLBACK_ACTIVE=0 export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp export CYCLONEDDS_URI="false" # shellcheck disable=SC1091 source /opt/ros/humble/setup.bash if [[ -f "${GO2_OS_UNITREE_SETUP:-$HOME/unitree_ros2/cyclonedds_ws/install/setup.bash}" ]]; then # shellcheck disable=SC1090 source "${GO2_OS_UNITREE_SETUP:-$HOME/unitree_ros2/cyclonedds_ws/install/setup.bash}" fi if [[ -f "$repo_root/install/setup.bash" ]]; then # shellcheck disable=SC1090 source "$repo_root/install/setup.bash" fi fi requested_ros_iface="${GO2_OS_DASHBOARD_IFACE:-${GO2_OS_NAV_IFACE:-${GO2_OS_WIRELESS_IFACE:-ens192}}}" requested_dds_peers="${GO2_DDS_PEERS:-${GO2_OS_DASHBOARD_PEERS:-${GO2_OS_NAV_PEERS:-${GO2_OS_DDS_PEERS:-}}}}" selected_ros_iface="${GO2_OS_ROS_IFACE}" selection_reason="${GO2_OS_SELECTED_IFACE_REASON:-}" blocking_error="${GO2_OS_NETWORK_BLOCKING_ERROR:-${blocking_error:-}}" warning_message="" if [[ "${GO2_OS_FALLBACK_ACTIVE:-0}" == "1" ]]; then warning_message="${selection_reason}" fi export OPEN_SOURCE_DASHBOARD_REQUESTED_ROS_IFACE="$requested_ros_iface" export OPEN_SOURCE_DASHBOARD_ROS_IFACE="$selected_ros_iface" export OPEN_SOURCE_DASHBOARD_DDS_PEERS="$requested_dds_peers" export OPEN_SOURCE_DASHBOARD_NETWORK_WARNING="$warning_message" export OPEN_SOURCE_DASHBOARD_NETWORK_POLICY="${GO2_OS_TRANSPORT_POLICY:-dashboard}" if [[ "${GO2_OS_TRANSPORT_POLICY:-}" == "wired_required" ]]; then network_primary_iface="${GO2_OS_WIRED_IFACE:-ens160}" network_fallback_iface="" else network_primary_iface="${GO2_OS_WIRELESS_IFACE:-ens192}" network_fallback_iface="${GO2_OS_WIRED_IFACE:-ens160}" fi export OPEN_SOURCE_DASHBOARD_NETWORK_PRIMARY_IFACE="$network_primary_iface" export OPEN_SOURCE_DASHBOARD_NETWORK_FALLBACK_IFACE="$network_fallback_iface" export OPEN_SOURCE_DASHBOARD_NETWORK_SELECTED_IFACE="$selected_ros_iface" export OPEN_SOURCE_DASHBOARD_NETWORK_SELECTION_REASON="$selection_reason" export OPEN_SOURCE_DASHBOARD_NETWORK_BLOCKING_ERROR="$blocking_error" export OPEN_SOURCE_DASHBOARD_NETWORK_FALLBACK_ACTIVE="${GO2_OS_FALLBACK_ACTIVE:-0}" cd "$repo_root" exec python3 go2_dashboard/server.py \ --host 0.0.0.0 \ --port "${OPEN_SOURCE_DASHBOARD_PORT:-8090}" \ --repo-root "$repo_root" \ --map-yaml "$HOME/go2_maps/competition_map.yaml" \ --camera-iface "${GO2_CAMERA_IFACE:-$selected_ros_iface}" \ --nav-log-dir "$repo_root/log/go2_nav" \ --pose-config "$repo_root/go2_dashboard/config/pose_pipeline.json" \ --waypoint-action-config "$repo_root/go2_dashboard/config/waypoint_action.json"