diff --git a/.gitignore b/.gitignore index 65dae27..8c3a6b0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ *.snap -squashfs-root -test* \ No newline at end of file +.snapcraft_store_credentials.txt +squashfs-root/ +**/snapcraft.yaml +exported.txt \ No newline at end of file diff --git a/demo/compose.yaml b/demo/compose.yaml index 6cd9d00..abac822 100644 --- a/demo/compose.yaml +++ b/demo/compose.yaml @@ -9,7 +9,7 @@ x-net-config: x-gpu-config: &gpu-config - runtime: nvidia + # runtime: nvidia environment: - DISPLAY=${DISPLAY:?err} - NVIDIA_VISIBLE_DEVICES=all @@ -23,16 +23,5 @@ services: container_name: rviz volumes: - /tmp/.X11-unix:/tmp/.X11-unix:rw - - ./config/rosbot_xl.rviz:/ros2_ws/install/rosbot_xl_manipulation_moveit/share/rosbot_xl_manipulation_moveit/config/moveit.rviz command: ros2 launch rosbot_xl_manipulation_moveit rviz.launch.py - joy2twist: - image: husarion/joy2twist:humble-1.0.0-20230204-stable - <<: *net-config - devices: - - /dev/input - volumes: - - ./config/joy2twist.yaml:/joy2twist.yaml - command: > - ros2 launch joy2twist gamepad_controller.launch.py - joy2twist_params_file:=/joy2twist.yaml \ No newline at end of file diff --git a/demo/config/joy2twist.yaml b/demo/config/joy2twist.yaml deleted file mode 100644 index 4806940..0000000 --- a/demo/config/joy2twist.yaml +++ /dev/null @@ -1,22 +0,0 @@ -/**: - ros__parameters: - linear_velocity_factor: - fast: 1.0 - regular: 0.5 - slow: 0.2 - - angular_velocity_factor: - fast: 1.5 - regular: 0.8 - slow: 0.4 - - # This button mapping should be adjusted to the specific controller - # The following map is suited for Logitech F710 - button_index_map: - axis: - angular_z: 2 # Right joystick - linear_x: 1 # Left joystick - linear_y: 0 # Left joystick - dead_man_switch: 4 # LB - fast_mode: 7 # RT - slow_mode: 5 # RB diff --git a/demo/net.env b/demo/net.env index a498c9c..63b7048 100644 --- a/demo/net.env +++ b/demo/net.env @@ -3,10 +3,10 @@ # ======================================= # 1. Fast DDS + LAN -# RMW_IMPLEMENTATION=rmw_fastrtps_cpp +RMW_IMPLEMENTATION=rmw_fastrtps_cpp # 2. Cyclone DDS + LAN -RMW_IMPLEMENTATION=rmw_cyclonedds_cpp +# RMW_IMPLEMENTATION=rmw_cyclonedds_cpp # 3. Fast DDS + VPN # RMW_IMPLEMENTATION=rmw_fastrtps_cpp diff --git a/justfile b/justfile index 953c7d8..43a696e 100644 --- a/justfile +++ b/justfile @@ -142,8 +142,8 @@ teleop: # export FASTRTPS_DEFAULT_PROFILES_FILE=$(pwd)/shm-only.xml ros2 run teleop_twist_keyboard teleop_twist_keyboard # --ros-args -r __ns:=/robot -iterate: - #!/bin/bash -e +iterate target="jazzy": + #!/bin/bash start_time=$(date +%s) echo "Starting script..." @@ -152,13 +152,31 @@ iterate: sudo rm -rf squashfs-root/ sudo rm -rf rosbot-xl*.snap export SNAPCRAFT_ENABLE_EXPERIMENTAL_EXTENSIONS=1 - snapcraft clean + + if [ {{target}} == "humble" ]; then + export ROS_DISTRO=humble + elif [ {{target}} == "jazzy" ]; then + export ROS_DISTRO=jazzy + else + echo "Unknown target: {{target}}" + exit 1 + fi + + if [ -f snap/snapcraft.yaml ]; then + snapcraft clean + sudo rm -rf snap/snapcraft.yaml + fi + + ./render_template.py ./snapcraft_template.yaml.jinja2 snap/snapcraft.yaml + chmod 444 snap/snapcraft.yaml snapcraft unsquashfs rosbot-xl*.snap sudo snap try squashfs-root/ sudo snap connect rosbot-xl:raw-usb sudo snap connect rosbot-xl:shm-plug rosbot-xl:shm-slot sudo snap connect rosbot-xl:shutdown + sudo snap connect rosbot-xl:hardware-observe + sudo snap connect rosbot-xl:joystick end_time=$(date +%s) duration=$(( end_time - start_time )) @@ -172,4 +190,16 @@ iterate: remove-logs: #!/bin/bash sudo rm -rf /var/log/journal/* - sudo systemctl restart systemd-journald \ No newline at end of file + sudo systemctl restart systemd-journald + +prepare-store-credentials: + #!/bin/bash + snapcraft export-login --snaps=rosbot-xl \ + --acls package_access,package_push,package_update,package_release \ + exported.txt + +publish: + #!/bin/bash + export SNAPCRAFT_STORE_CREDENTIALS=$(cat exported.txt) + snapcraft login + snapcraft upload --release edge rosbot-xl*.snap \ No newline at end of file diff --git a/snap/hooks/configure b/snap/hooks/configure index 856672f..d895219 100644 --- a/snap/hooks/configure +++ b/snap/hooks/configure @@ -9,11 +9,9 @@ source $SNAP/usr/bin/utils.sh # Define the top-level key and the list of valid keys VALID_DRIVER_KEYS=("mecanum" "include-camera-mount" "camera-model" "lidar-model" "db-serial-port" "manipulator-serial-port" ) -VALID_WEBUI_KEYS=("layout" "port") # Call the validation function validate_keys "driver" VALID_DRIVER_KEYS[@] -validate_keys "webui" VALID_WEBUI_KEYS[@] # Define the valid options for camera model and lidar model VALID_CAMERA_OPTIONS=("None" "intel_realsense_d435" "orbbec_astra" "stereolabs_zed" "stereolabs_zedm" "stereolabs_zed2" "stereolabs_zed2i" "stereolabs_zedx" "stereolabs_zedxm") @@ -27,25 +25,10 @@ validate_option "driver.mecanum" VALID_BOOLEAN_OPTIONS[@] validate_option "driver.include-camera-mount" VALID_BOOLEAN_OPTIONS[@] # Validate specific serial ports -validate_serial_port "driver.db-serial-port" -validate_serial_port "driver.manipulator-serial-port" - -# Get the transport setting using snapctl -OPT="webui.layout" -LAYOUT="$(snapctl get ${OPT})" - -# Only exit with status 1 if conditions are not met -if [ ! -f "${SNAP_COMMON}/foxglove-${LAYOUT}.json" ]; then - log_and_echo "'${SNAP_COMMON}/foxglove-${LAYOUT}.json' does not exist." - exit 1 -fi - -# Make sure WEBUI_PORT is valid -EXCLUDED_PORTS=(3000 8888) -SUPPORTED_RANGE=(0 65535) - -# Validate a specific port, for example, webui.port -validate_number "webui.port" SUPPORTED_RANGE[@] EXCLUDED_PORTS[@] +# validate driver.serial-port +ALTERNATIVE_SERIAL_PORT_OPTIONS=("auto") +validate_path "driver.db-serial-port" "/dev/ttyUSB[0-9]+" ALTERNATIVE_SERIAL_PORT_OPTIONS[@] +validate_path "driver.manipulator-serial-port" "/dev/ttyUSB[0-9]+" ALTERNATIVE_SERIAL_PORT_OPTIONS[@] VALID_CONFIGURATION_OPTIONS=("basic" "manipulation") @@ -65,7 +48,7 @@ fi $SNAP/usr/bin/configure_hook_ros.sh # restart services with new ROS 2 config -for service in daemon web-ui web-ws joy teleop-twist-joy; do +for service in daemon joy; do if snapctl services ${SNAP_NAME}.${service} | grep -qw enabled; then snapctl restart ${SNAP_NAME}.${service} log "Restarted ${SNAP_NAME}.${service}" diff --git a/snap/hooks/connect-plug-ros-humble-ros-base b/snap/hooks/connect-plug-ros-humble-ros-base deleted file mode 100644 index 39d5c18..0000000 --- a/snap/hooks/connect-plug-ros-humble-ros-base +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -e - -# now we can start the service -# if snapctl services ${SNAP_NAME}.${SNAP_NAME} | grep -q inactive; then -# snapctl start --enable ${SNAP_NAME}.${SNAP_NAME} 2>&1 || true -# fi - -logger -t ${SNAP_NAME} "Plug 'ros-humble-ros-base' connected" \ No newline at end of file diff --git a/snap/hooks/disconnect-plug-ros-humble-ros-base b/snap/hooks/disconnect-plug-ros-humble-ros-base deleted file mode 100644 index bc2c60d..0000000 --- a/snap/hooks/disconnect-plug-ros-humble-ros-base +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -e - -logger -t ${SNAP_NAME} "Plug 'ros-humble-ros-base' disconnected" -snapctl stop --disable ${SNAP_NAME}.daemon 2>&1 || true diff --git a/snap/hooks/install b/snap/hooks/install index 8b4bea7..bbdb65e 100644 --- a/snap/hooks/install +++ b/snap/hooks/install @@ -14,9 +14,6 @@ snapctl set driver.lidar-model=None snapctl set driver.db-serial-port=auto snapctl set driver.manipulator-serial-port=auto -snapctl set webui.layout=default -snapctl set webui.port=8080 - snapctl set configuration=basic if ! snapctl is-connected raw-usb; then @@ -24,11 +21,11 @@ if ! snapctl is-connected raw-usb; then log "sudo snap connect ${SNAP_NAME}:raw-usb" fi -# copy meshes to shared folder -log "copy meshes to '${SNAP_COMMON}/ros2_ws/'" -mkdir -p ${SNAP_COMMON}/ros2_ws -cp -r $SNAP/opt/ros/snap/share/rosbot_xl_description ${SNAP_COMMON}/ros2_ws/rosbot_xl_description -cp -r $SNAP/opt/ros/snap/share/ros_components_description ${SNAP_COMMON}/ros2_ws/ros_components_description +# # copy meshes to shared folder +# log "copy meshes to '${SNAP_COMMON}/ros2_ws/'" +# mkdir -p ${SNAP_COMMON}/ros2_ws +# cp -r $SNAP/opt/ros/snap/share/rosbot_xl_description ${SNAP_COMMON}/ros2_ws/rosbot_xl_description +# cp -r $SNAP/opt/ros/snap/share/ros_components_description ${SNAP_COMMON}/ros2_ws/ros_components_description # copy joy params cp -r $SNAP/usr/share/rosbot-xl/config/teleop_twist_joy_params.yaml ${SNAP_COMMON}/ @@ -38,5 +35,5 @@ cp -r $SNAP/usr/share/rosbot-xl/config/joy_servo.yaml ${SNAP_COMMON}/ cp -r $SNAP/usr/share/rosbot-xl/config/joy_teleop.config.yaml ${SNAP_COMMON}/ cp -r $SNAP/usr/share/rosbot-xl/config/joy_params.yaml ${SNAP_COMMON}/ -# copy webui layouts -cp -r $SNAP/usr/share/$SNAP_NAME/config/foxglove-*.json ${SNAP_COMMON}/ \ No newline at end of file +# # copy webui layouts +# cp -r $SNAP/usr/share/$SNAP_NAME/config/foxglove-*.json ${SNAP_COMMON}/ \ No newline at end of file diff --git a/snap/local/Caddyfile b/snap/local/Caddyfile deleted file mode 100644 index 70edc28..0000000 --- a/snap/local/Caddyfile +++ /dev/null @@ -1,48 +0,0 @@ -# :8080 { -# # Serve static files from /var/www/foxglove -# root * /var/www/foxglove - -# # Handle all requests -# file_server -# } - -:{$UI_PORT} { - # Enable HTTP/2 over clear text (h2c) - # protocols h2c - - # Reverse Proxy for WebSocket connections on /ws - handle_path /ws { - reverse_proxy http://127.0.0.1:8765 - } - - # Reverse Proxy for the main site - handle_path /* { - # reverse_proxy http://127.0.0.1:8080 - # Serve static files from /var/www/foxglove - root * {$SNAP_DATA}/www/foxglove/ - - @ipv6Client { - expression {http.request.host}.startsWith("fc94") - } - - handle @ipv6Client { - vars full_host [{http.request.host}] - redir /ui /?ds=foxglove-websocket&ds.url=ws%3A%2F%2F%5B{http.request.host}%5D%3A{http.request.port}%2Fws - } - - # Handle all other requests (from non-IPv6 clients) - handle { - vars full_host {http.request.host} - redir /ui /?ds=foxglove-websocket&ds.url=ws%3A%2F%2F{http.request.host}%3A{http.request.port}%2Fws - } - - # Handle envs in foxglove templates - templates { - mime "text/html" - # mime "application/json" "text/plain" "text/html" - } - - # Handle all requests - file_server - } -} diff --git a/snap/local/bridge_launch.py b/snap/local/bridge_launch.py deleted file mode 100755 index 965b95f..0000000 --- a/snap/local/bridge_launch.py +++ /dev/null @@ -1,24 +0,0 @@ -import os -from launch import LaunchDescription -from launch_ros.actions import Node - -def generate_launch_description(): - - # Node configuration for foxglove_bridge - foxglove_bridge = Node( - package='foxglove_bridge', - executable='foxglove_bridge', - name='foxglove_bridge', - parameters=[{ - 'port': 8765, - 'address': '127.0.0.1', - 'capabilities': ['clientPublish', 'parameters', 'parametersSubscribe', 'services', 'connectionGraph', 'assets'] - # 'capabilities': ['clientPublish', 'connectionGraph', 'assets'] - }], - output='screen' - ) - - # Return the launch description which includes both nodes and the launch argument - return LaunchDescription([ - foxglove_bridge, - ]) diff --git a/snap/local/bridge_launcher.sh b/snap/local/bridge_launcher.sh deleted file mode 100755 index f34213b..0000000 --- a/snap/local/bridge_launcher.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash -e - -LAUNCH_OPTIONS="" - -# Retrieve the namespace using snapctl -NAMESPACE="$(snapctl get ros.namespace)" - -# Check if NAMESPACE is not set or is empty -if [ -n "$NAMESPACE" ]; then - LAUNCH_OPTIONS+="namespace:=${NAMESPACE} " -fi - -ros2 launch $SNAP/usr/bin/bridge_launch.py ${LAUNCH_OPTIONS} diff --git a/snap/local/caddy_launcher.sh b/snap/local/caddy_launcher.sh deleted file mode 100755 index 75b2bc8..0000000 --- a/snap/local/caddy_launcher.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/bash -e - -# Define a function to log and echo messages -source $SNAP/usr/bin/utils.sh - -# Define the source and destination directories -site_path="$SNAP/usr/local/www/" -site_tmp_path="$SNAP_DATA/www/" -layout="$(snapctl get webui.layout)" -# layout="layout" -export UI_PORT="$(snapctl get webui.port)" -log_and_echo "Using ${SNAP_COMMON}/foxglove-$layout.json" - -# Ensure the destination directory exists -rm -rf $site_tmp_path -mkdir -p "$site_tmp_path" - -# Copy foxglove folder to temp path -cp -R $site_path/foxglove $site_tmp_path - -# apply the layout -index_html_path=$site_tmp_path/foxglove/index.html -index_html_content=$(cat $index_html_path) -replace_pattern='/*FOXGLOVE_STUDIO_DEFAULT_LAYOUT_PLACEHOLDER*/' -replace_value=$(cat ${SNAP_COMMON}/foxglove-$layout.json) -echo "${index_html_content/"$replace_pattern"/$replace_value}" > $index_html_path - -# disable cache -sed -i "s|
|\n&|" $index_html_path - -# Define a function to log and echo messages -# Retrieve the ros.namespace value -namespace=$(snapctl get ros.namespace) - -# Check if the namespace is set and not empty -if [ -n "$namespace" ]; then - # Set the environment variable - export NAMESPACE="/$namespace" -fi -caddy run --config $SNAP/usr/share/$SNAP_NAME/config/Caddyfile --adapter caddyfile - diff --git a/snap/local/flash_launcher.sh b/snap/local/flash_launcher.sh index ef6ef46..deed7bf 100755 --- a/snap/local/flash_launcher.sh +++ b/snap/local/flash_launcher.sh @@ -19,7 +19,7 @@ else fi # Check if SERIAL_PORT is set to auto or specified -SERIAL_PORT=$(find_ttyUSB driver.db-serial-port "0403" "6015") +SERIAL_PORT=$(find_usb_device "ttyUSB" driver.db-serial-port "0403" "6015") if [ $? -ne 0 ]; then log_and_echo "Failed to find the serial port." exit 1 diff --git a/snap/local/foxglove-default.json b/snap/local/foxglove-default.json deleted file mode 100644 index 43c72a1..0000000 --- a/snap/local/foxglove-default.json +++ /dev/null @@ -1,145 +0,0 @@ -{ - "configById": { - "Teleop!3yjcv6d": { - "topic": "{{env "NAMESPACE"}}/cmd_vel", - "publishRate": 10, - "upButton": { - "field": "linear-x", - "value": 1 - }, - "downButton": { - "field": "linear-x", - "value": -1 - }, - "leftButton": { - "field": "angular-z", - "value": 1 - }, - "rightButton": { - "field": "angular-z", - "value": -1 - } - }, - "3D!36yxwbl": { - "cameraState": { - "perspective": true, - "distance": 2.2036622046999295, - "phi": 59.99999999999968, - "thetaOffset": 45.000000000000036, - "targetOffset": [ - -0.1884647536706241, - 0.13784349522327283, - -3.166224866510698e-17 - ], - "target": [ - 0, - 0, - 0 - ], - "targetOrientation": [ - 0, - 0, - 0, - 1 - ], - "fovy": 45, - "near": 0.5, - "far": 5000 - }, - "followMode": "follow-pose", - "scene": {}, - "transforms": { - "frame:antenna_link": { - "visible": false - }, - "frame:antenna_connector_link": { - "visible": false - }, - "frame:body_link": { - "visible": false - }, - "frame:base_link": { - "visible": true - }, - "frame:cover_link": { - "visible": false - }, - "frame:imu_link": { - "visible": false - }, - "frame:camera_mount_mid_link": { - "visible": false - }, - "frame:camera_mount_bot_link": { - "visible": false - }, - "frame:camera_mount_top_link": { - "visible": false - }, - "frame:camera_mount_link": { - "visible": false - }, - "frame:slamtec_rplidar_s1_link": { - "visible": false - }, - "frame:laser": { - "visible": false - }, - "frame:fl_wheel_link": { - "visible": false - }, - "frame:fr_wheel_link": { - "visible": false - }, - "frame:rl_wheel_link": { - "visible": false - }, - "frame:rr_wheel_link": { - "visible": false - }, - "frame:odom": { - "visible": true - } - }, - "topics": {}, - "layers": { - "48c64d32-2812-4be5-9335-65c414e3722d": { - "visible": true, - "frameLocked": true, - "label": "URDF", - "instanceId": "48c64d32-2812-4be5-9335-65c414e3722d", - "layerId": "foxglove.Urdf", - "sourceType": "topic", - "url": "", - "filePath": "", - "parameter": "", - "topic": "{{env "NAMESPACE"}}/robot_description", - "framePrefix": "", - "displayMode": "auto", - "fallbackColor": "#ffffff", - "order": 1 - } - }, - "publish": { - "type": "point", - "poseTopic": "{{env "NAMESPACE"}}/move_base_simple/goal", - "pointTopic": "{{env "NAMESPACE"}}/clicked_point", - "poseEstimateTopic": "{{env "NAMESPACE"}}/initialpose", - "poseEstimateXDeviation": 0.5, - "poseEstimateYDeviation": 0.5, - "poseEstimateThetaDeviation": 0.26179939 - }, - "imageMode": {} - } - }, - "globalVariables": {}, - "userNodes": {}, - "playbackConfig": { - "speed": 1 - }, - "layout": { - "direction": "row", - "first": "3D!36yxwbl", - "second": "Teleop!3yjcv6d" - } -} \ No newline at end of file diff --git a/snap/local/foxglove-sensors.json b/snap/local/foxglove-sensors.json deleted file mode 100644 index 783cd67..0000000 --- a/snap/local/foxglove-sensors.json +++ /dev/null @@ -1,445 +0,0 @@ -{ - "configById": { - "Plot!1u5bb0v": { - "paths": [ - { - "value": "{{env "NAMESPACE"}}/imu_broadcaster/imu.orientation.w", - "enabled": true, - "timestampMethod": "receiveTime" - }, - { - "value": "{{env "NAMESPACE"}}/imu_broadcaster/imu.orientation.x", - "enabled": true, - "timestampMethod": "receiveTime" - }, - { - "value": "{{env "NAMESPACE"}}/imu_broadcaster/imu.orientation.y", - "enabled": true, - "timestampMethod": "receiveTime" - }, - { - "value": "{{env "NAMESPACE"}}/imu_broadcaster/imu.orientation.z", - "enabled": true, - "timestampMethod": "receiveTime" - } - ], - "minYValue": -1.1, - "maxYValue": 1.1, - "showXAxisLabels": true, - "showYAxisLabels": true, - "showLegend": false, - "legendDisplay": "floating", - "showPlotValuesInLegend": false, - "isSynced": true, - "xAxisVal": "timestamp", - "sidebarDimension": 240, - "foxglovePanelTitle": "Plot", - "followingViewWidth": 30 - }, - "RosOut!b0toow": { - "searchTerms": [], - "minLogLevel": 2 - }, - "Publish!3yfprcp": { - "topicName": "{{env "NAMESPACE"}}/cmd_vel", - "datatype": "geometry_msgs/msg/Twist", - "buttonText": "Motors Test", - "buttonTooltip": "", - "buttonColor": "#a85600", - "advancedView": false, - "value": "{\n \"linear\": {\n \"x\": 1.0,\n \"y\": 0,\n \"z\": 0\n },\n \"angular\": {\n \"x\": 0,\n \"y\": 0,\n \"z\": -0.5\n }\n}" - }, - "3D!4atcr8w": { - "cameraState": { - "perspective": true, - "distance": 4.078136514915201, - "phi": 0.27634279333612527, - "thetaOffset": 88.9293939734993, - "targetOffset": [ - 0.34677234754289576, - 0.03223816139348337, - -2.8618304713627643e-18 - ], - "target": [ - 0, - 0, - 0 - ], - "targetOrientation": [ - 0, - 0, - 0, - 1 - ], - "fovy": 45, - "near": 0.5, - "far": 5000 - }, - "followMode": "follow-pose", - "scene": {}, - "transforms": { - "frame:antenna_link": { - "visible": false - }, - "frame:antenna_connector_link": { - "visible": false - }, - "frame:body_link": { - "visible": false - }, - "frame:base_link": { - "visible": false - }, - "frame:cover_link": { - "visible": false - }, - "frame:imu_link": { - "visible": false - }, - "frame:camera_mount_mid_link": { - "visible": false - }, - "frame:camera_mount_bot_link": { - "visible": false - }, - "frame:camera_mount_top_link": { - "visible": false - }, - "frame:camera_mount_link": { - "visible": false - }, - "frame:slamtec_rplidar_s1_link": { - "visible": false - }, - "frame:laser": { - "visible": false - }, - "frame:odom": { - "visible": false - }, - "frame:fl_wheel_link": { - "visible": false - }, - "frame:fr_wheel_link": { - "visible": false - }, - "frame:rl_wheel_link": { - "visible": false - }, - "frame:rr_wheel_link": { - "visible": false - } - }, - "topics": { - "{{env "NAMESPACE"}}/robot_description": { - "visible": true - }, - "{{env "NAMESPACE"}}/scan": { - "visible": false, - "colorField": "intensity", - "colorMode": "colormap", - "colorMap": "turbo", - "pointSize": 6 - }, - "{{env "NAMESPACE"}}/scan_filtered": { - "visible": true, - "colorField": "intensity", - "colorMode": "colormap", - "colorMap": "turbo", - "pointSize": 6 - } - }, - "layers": { - "65f38642-dc67-4219-8e4d-bb0330368f80": { - "visible": true, - "frameLocked": true, - "label": "URDF", - "instanceId": "65f38642-dc67-4219-8e4d-bb0330368f80", - "layerId": "foxglove.Urdf", - "sourceType": "topic", - "url": "", - "filePath": "", - "parameter": "", - "topic": "{{env "NAMESPACE"}}/robot_description", - "framePrefix": "", - "displayMode": "auto", - "fallbackColor": "#ffffff", - "order": 1 - }, - "eebc5132-8e96-40f6-a746-e61c0daaedab": { - "visible": true, - "frameLocked": true, - "label": "Grid", - "instanceId": "eebc5132-8e96-40f6-a746-e61c0daaedab", - "layerId": "foxglove.Grid", - "size": 10, - "divisions": 10, - "lineWidth": 1, - "color": "#248eff", - "position": [ - 0, - 0, - 0 - ], - "rotation": [ - 0, - 0, - 0 - ], - "order": 1 - } - }, - "publish": { - "type": "point", - "poseTopic": "{{env "NAMESPACE"}}/move_base_simple/goal", - "pointTopic": "{{env "NAMESPACE"}}/clicked_point", - "poseEstimateTopic": "{{env "NAMESPACE"}}/initialpose", - "poseEstimateXDeviation": 0.5, - "poseEstimateYDeviation": 0.5, - "poseEstimateThetaDeviation": 0.26179939 - }, - "imageMode": {} - }, - "Tab!2qhku9u": { - "activeTabIdx": 0, - "tabs": [ - { - "title": "IMU Plots", - "layout": { - "first": "Plot!1u5bb0v", - "second": "RosOut!b0toow", - "direction": "column" - } - }, - { - "title": "Production", - "layout": "Publish!3yfprcp" - } - ] - }, - "Image!2zw8l2a": { - "cameraState": { - "distance": 20, - "perspective": true, - "phi": 60, - "target": [ - 0, - 0, - 0 - ], - "targetOffset": [ - 0, - 0, - 0 - ], - "targetOrientation": [ - 0, - 0, - 0, - 1 - ], - "thetaOffset": 45, - "fovy": 45, - "near": 0.5, - "far": 5000 - }, - "followMode": "follow-pose", - "scene": {}, - "transforms": {}, - "topics": {}, - "layers": {}, - "publish": { - "type": "point", - "poseTopic": "{{env "NAMESPACE"}}/move_base_simple/goal", - "pointTopic": "{{env "NAMESPACE"}}/clicked_point", - "poseEstimateTopic": "{{env "NAMESPACE"}}/initialpose", - "poseEstimateXDeviation": 0.5, - "poseEstimateYDeviation": 0.5, - "poseEstimateThetaDeviation": 0.26179939 - }, - "imageMode": { - "imageTopic": "{{env "NAMESPACE"}}/oak/rgb/image_raw/compressed", - "calibrationTopic": "{{env "NAMESPACE"}}/oak/rgb/camera_info" - } - }, - "Teleop!13emlz4": { - "topic": "{{env "NAMESPACE"}}/cmd_vel", - "publishRate": 10, - "upButton": { - "field": "linear-x", - "value": 0.19754204525471783 - }, - "downButton": { - "field": "linear-x", - "value": -0.20000000000000015 - }, - "leftButton": { - "field": "angular-z", - "value": 1 - }, - "rightButton": { - "field": "angular-z", - "value": -1 - }, - "foxglovePanelTitle": "Diff Drive" - }, - "Gauge!4jffafa": { - "path": "/battery_state.voltage", - "minValue": 9.8, - "maxValue": 12.6, - "colorMap": "red-yellow-green", - "colorMode": "colormap", - "gradient": [ - "#0000ff", - "#ff00ff" - ], - "reverse": false, - "foxglovePanelTitle": "Battery" - }, - "Indicator!11kizr9": { - "path": "/battery_state.voltage", - "style": "background", - "fallbackColor": "#000000", - "fallbackLabel": "Ok", - "rules": [ - { - "operator": "<", - "rawValue": "10.8", - "color": "#ff0000", - "label": "Plug charger!" - } - ], - "foxglovePanelTitle": "Plug Charger Info" - }, - "Plot!4dl4s92": { - "paths": [ - { - "value": "/battery_state.voltage", - "enabled": true, - "timestampMethod": "receiveTime" - } - ], - "minYValue": 9.482842712474614, - "maxYValue": 13, - "showXAxisLabels": true, - "showYAxisLabels": true, - "showLegend": true, - "legendDisplay": "floating", - "showPlotValuesInLegend": true, - "isSynced": true, - "xAxisVal": "timestamp", - "sidebarDimension": 240, - "foxglovePanelTitle": "Voltage", - "followingViewWidth": 60 - }, - "Gauge!43atfmu": { - "path": "/battery_state.current", - "minValue": -3, - "maxValue": 3, - "colorMap": "red-yellow-green", - "colorMode": "colormap", - "gradient": [ - "#0000ff", - "#ff00ff" - ], - "reverse": true, - "foxglovePanelTitle": "Battery Current" - }, - "Gauge!1t2ifzu": { - "path": "/battery_state.charge", - "minValue": 0, - "maxValue": 3, - "colorMap": "red-yellow-green", - "colorMode": "colormap", - "gradient": [ - "#0000ff", - "#ff00ff" - ], - "reverse": true, - "foxglovePanelTitle": "Battery Charger Current" - }, - "Plot!3gmoqow": { - "paths": [ - { - "value": "/battery_state.current", - "enabled": true, - "timestampMethod": "receiveTime" - }, - { - "value": "/battery_state.charge", - "enabled": true, - "timestampMethod": "receiveTime" - } - ], - "minYValue": -3, - "maxYValue": 3, - "showXAxisLabels": true, - "showYAxisLabels": true, - "showLegend": true, - "legendDisplay": "floating", - "showPlotValuesInLegend": true, - "isSynced": true, - "xAxisVal": "timestamp", - "sidebarDimension": 240, - "foxglovePanelTitle": "Current" - } - }, - "globalVariables": { - "globalVariable": 7 - }, - "userNodes": { - "f5206e1d-deee-4f90-a03e-f561fbb9a7dd": { - "sourceCode": "// The ./types module provides helper types for your Input events and messages.\nimport { Input, Message } from \"./types\";\n\n// Your script can output well-known message types, any of your custom message types, or\n// complete custom message types.\n//\n// Use `Message` to access your data source types or well-known types:\n// type Twist = Message<\"geometry_msgs/Twist\">;\n//\n// Conventionally, it's common to make a _type alias_ for your script's output type\n// and use that type name as the return type for your script function.\n// Here we've called the type `Output` but you can pick any type name.\ntype Output = {\n hello: string;\n};\n\n// These are the topics your script \"subscribes\" to. Studio will invoke your script function\n// when any message is received on one of these topics.\nexport const inputs = [\"/input/topic\"];\n\n// Any output your script produces is \"published\" to this topic. Published messages are only visible within Studio, not to your original data source.\nexport const output = \"/studio_script/output_topic\";\n\n// This function is called with messages from your input topics.\n// The first argument is an event with the topic, receive time, and message.\n// Use the `Input<...>` helper to get the correct event type for your input topic messages.\nexport default function script(event: Input<\"/input/topic\">): Output {\n return {\n hello: \"world!\",\n };\n};", - "name": "f5206e1d" - }, - "1a9e6183-d4b1-47dd-a024-efc14ab90b6b": { - "sourceCode": "// This example shows how to subscribe to multiple input topics.\n//\n// NOTE:\n// User Scripts can subscribe to multiple input topics, but can only publish on a single topic.\n\nimport { Input } from \"./types\";\n\ntype Output = { topic: string };\ntype GlobalVariables = { id: number };\n\n// List all the input topics in the `input` array\nexport const inputs = [\"/input/topic\", \"/input/another\"];\nexport const output = \"/studio_script/output_topic\";\n\n// Make an InputEvent type alias. Since our node will get a message from either input topic, we need to enumerate the topics.\ntype InputEvent = Input<\"/input/topic\"> | Input<\"/input/another\">;\n\nexport default function node(event: InputEvent, globalVars: GlobalVariables): Output {\n // Remember that your node will get messages on each topic, so you\n // need to check each event's topic to know which fields are available on the message.\n switch (event.topic) {\n case \"/input/topic\":\n // topic specific input logic\n // Our message fields are specific to our topic message\n break;\n case \"/input/another\":\n // another specific logic\n break;\n }\n\n // Nodes can only output one type of message regardless of the inputs\n // Here we echo back the input topic as an example.\n return {\n topic: event.topic,\n };\n};\n", - "name": "1a9e6183" - } - }, - "playbackConfig": { - "speed": 1 - }, - "layout": { - "first": { - "direction": "row", - "first": "Tab!2qhku9u", - "second": { - "first": "3D!4atcr8w", - "second": { - "first": "Teleop!13emlz4", - "second": "Image!2zw8l2a", - "direction": "column" - }, - "direction": "row" - }, - "splitPercentage": 30.5849582172702 - }, - "second": { - "first": { - "first": "Gauge!4jffafa", - "second": "Indicator!11kizr9", - "direction": "column" - }, - "second": { - "first": "Plot!4dl4s92", - "second": { - "first": { - "first": "Gauge!43atfmu", - "second": "Gauge!1t2ifzu", - "direction": "column" - }, - "second": "Plot!3gmoqow", - "direction": "row", - "splitPercentage": 40.95744286095124 - }, - "direction": "row", - "splitPercentage": 38.157892540045665 - }, - "direction": "row", - "splitPercentage": 18.12550403728454 - }, - "direction": "column", - "splitPercentage": 67.44897959183673 - } -} \ No newline at end of file diff --git a/snap/local/foxglove-set-namespace.sh b/snap/local/foxglove-set-namespace.sh deleted file mode 100755 index e1fe76c..0000000 --- a/snap/local/foxglove-set-namespace.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash -e - -# deprecated (using caddy templates instead) - -LAYOUT="$(snapctl get webui.layout)" -NAMESPACE="$(snapctl get driver.namespace)" - -cp ${SNAP_COMMON}/foxglove-${LAYOUT}.json ${SNAP_COMMON}/foxglove-layout.json - -if [ -n "$NAMESPACE" ]; then - # Update path fields - yq -i -o=json '(.configById[] | select(has("path")) | .path) |= "/'$NAMESPACE'" + .' ${SNAP_COMMON}/foxglove-layout.json - - # Update paths[].value fields - yq -i -o=json '(.configById[] | select(has("paths")) | .paths[].value) |= "/'$NAMESPACE'" + .' ${SNAP_COMMON}/foxglove-layout.json - - # Update topicName fields - yq -i -o=json '(.configById[] | select(has("topicName")) | .topicName) |= "/'$NAMESPACE'" + .' ${SNAP_COMMON}/foxglove-layout.json - - # Update topic fields - yq -i -o=json '(.configById[] | select(has("topic")) | .topic) |= "/'$NAMESPACE'" + .' ${SNAP_COMMON}/foxglove-layout.json - - # Update keys within topics - yq -i -o=json '(.configById[] | select(has("topics")) | .topics) |= with_entries(.key |= "/'$NAMESPACE'" + .)' ${SNAP_COMMON}/foxglove-layout.json - - # Update values of keys matching .*Topic$ - yq -i -o=json '(.configById[] | select(has("publish")) | .publish | select(has("poseTopic")) | .poseTopic) |= "/'$NAMESPACE'" + .' ${SNAP_COMMON}/foxglove-layout.json - yq -i -o=json '(.configById[] | select(has("publish")) | .publish | select(has("pointTopic")) | .pointTopic) |= "/'$NAMESPACE'" + .' ${SNAP_COMMON}/foxglove-layout.json - yq -i -o=json '(.configById[] | select(has("publish")) | .publish | select(has("poseEstimateTopic")) | .poseEstimateTopic) |= "/'$NAMESPACE'" + .' ${SNAP_COMMON}/foxglove-layout.json - - # Update imageTopic - yq -i -o=json '(.configById[] | select(has("imageMode")) | .imageMode | select(has("imageTopic")) | .imageTopic) |= "/'$NAMESPACE'" + .' ${SNAP_COMMON}/foxglove-layout.json -fi diff --git a/snap/local/ftdi_eeprom_conf_launcher.sh b/snap/local/ftdi_eeprom_conf_launcher.sh index 34854ef..e2331fc 100755 --- a/snap/local/ftdi_eeprom_conf_launcher.sh +++ b/snap/local/ftdi_eeprom_conf_launcher.sh @@ -8,4 +8,6 @@ if [ "$(id -u)" -ne 0 ]; then exit 1 fi +export PYTHONPATH=$SNAP/usr/lib/python3/dist-packages + $SNAP/usr/bin/ftdi_eeprom_conf.py \ No newline at end of file diff --git a/snap/local/joy.launch.py b/snap/local/joy.launch.py new file mode 100755 index 0000000..efa6da0 --- /dev/null +++ b/snap/local/joy.launch.py @@ -0,0 +1,65 @@ +import os + +from ament_index_python.packages import get_package_share_directory + +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument +from launch.substitutions import LaunchConfiguration +from launch_ros.actions import Node + + +def generate_launch_description(): + joy_dev = LaunchConfiguration('joy_dev') + config_filepath = LaunchConfiguration('config_filepath') + publish_stamped_twist = LaunchConfiguration('publish_stamped_twist') + namespace = LaunchConfiguration('namespace') # Capture the namespace + + return LaunchDescription([ + DeclareLaunchArgument( + 'joy_vel', + default_value='cmd_vel', + description='The topic name to which velocity commands will be published.' + ), + DeclareLaunchArgument( + 'joy_dev', + default_value='/dev/input/js0', + description='The device file for the joystick (e.g., /dev/input/js0).' + ), + DeclareLaunchArgument( + 'config_filepath', + default_value=[ + os.path.join(os.environ.get("SNAP_COMMON"), 'joy_teleop.config.yaml') + ], + description='The file path to the configuration YAML file for the teleop_twist_joy node.' + ), + DeclareLaunchArgument( + 'publish_stamped_twist', + default_value='false', # Default set to false + description='Flag to control whether to publish geometry_msgs/TwistStamped messages instead of geometry_msgs/Twist.' + ), + DeclareLaunchArgument( + 'namespace', + default_value='', + description='Optional namespace to apply to the nodes and remapped topics. If left empty, no namespace is applied.' + ), + + Node( + package='joy', + executable='joy_node', + name='joy_node', + namespace=namespace, # Apply the namespace here + parameters=[{ + 'dev': joy_dev, + 'deadzone': 0.3, + 'autorepeat_rate': 20.0, + }] + ), + Node( + package='teleop_twist_joy', + executable='teleop_node', + name='teleop_twist_joy_node', + namespace=namespace, # Apply the namespace here + parameters=[config_filepath, {'publish_stamped_twist': publish_stamped_twist}], + remappings={('/cmd_vel', LaunchConfiguration('joy_vel'))}, # Remap the topic under the namespace + ), + ]) diff --git a/snap/local/joy_launcher.sh b/snap/local/joy_launcher.sh index b41f19a..731fb27 100755 --- a/snap/local/joy_launcher.sh +++ b/snap/local/joy_launcher.sh @@ -1,19 +1,38 @@ #!/bin/bash -e -ros2 run joy joy_node --ros-args --params-file $SNAP_COMMON/joy_params.yaml - -# # Retrieve the namespace using snapctl -# NAMESPACE="$(snapctl get ros.namespace)" - -# # Check if NAMESPACE is not set or is empty -# if [ -z "$NAMESPACE" ]; then -# # No namespace is set, run the launch command without the namespace argument -# ros2 launch teleop_twist_joy teleop-launch.py \ -# config_filepath:=$SNAP_COMMON/joy_teleop.config.yaml -# # ros2 launch teleop_twist_joy teleop-launch.py -# else -# # Namespace is set, include it in the launch command -# ros2 launch teleop_twist_joy teleop-launch.py \ -# config_filepath:=$SNAP_COMMON/joy_teleop.config.yaml --ros-args -r __ns:=/$NAMESPACE -# # ros2 launch teleop_twist_joy teleop-launch.py --ros-args -r __ns:=/$NAMESPACE -# fi +source $SNAP/usr/bin/utils.sh + +# Retrieve the namespace using snapctl +NAMESPACE="$(snapctl get ros.namespace)" + +# Initialize the launch arguments +LAUNCH_ARGS="config_filepath:=$SNAP_COMMON/joy_teleop.config.yaml" + +# If NAMESPACE is set, append the namespace argument +if [ -n "$NAMESPACE" ]; then + LAUNCH_ARGS="$LAUNCH_ARGS namespace:=/$NAMESPACE" +fi + +# If ROS_DISTRO is jazzy, append the publish_stamped_twist argument +if [ "$ROS_DISTRO" == "jazzy" ]; then + LAUNCH_ARGS="$LAUNCH_ARGS publish_stamped_twist:=true" +elif [ "$ROS_DISTRO" == "humble" ]; then + LAUNCH_ARGS="$LAUNCH_ARGS publish_stamped_twist:=false" +fi + +# export LD_LIBRARY_PATH="$SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/pulseaudio:$LD_LIBRARY_PATH" + +# export LD_LIBRARY_PATH="$SNAP/usr/lib/aarch64-linux-gnu/pulseaudio/libpulsecommon-16.1.so:$LD_LIBRARY_PATH" + +# export LD_LIBRARY_PATH=/snap/${SNAP_NAME}/x1/opt/ros/snap/lib:/snap/${SNAP_NAME}/x1/opt/ros/humble/lib/aarch64-linux-gnu:/snap/${SNAP_NAME}/x1/opt/ros/humble/lib:/snap/${SNAP_NAME}/x1/opt/ros/underlay_ws/usr/lib:/snap/${SNAP_NAME}/x1/opt/ros/underlay_ws/usr/lib/aarch64-linux-gnu:/snap/${SNAP_NAME}/x1/opt/ros/underlay_ws/opt/ros/humble/lib/aarch64-linux-gnu:/snap/${SNAP_NAME}/x1/opt/ros/underlay_ws/opt/ros/humble/lib:/snap/${SNAP_NAME}/x1/usr/lib/aarch64-linux-gnu/pulseaudio:/var/lib/snapd/lib/gl:/var/lib/snapd/lib/gl32:/var/lib/snapd/void:/snap/${SNAP_NAME}/x1/usr/lib:/snap/${SNAP_NAME}/x1/usr/lib/aarch64-linux-gnu +# echo $LD_LIBRARY_PATH + +if [ "${LAUNCH_ARGS}" ]; then + # watch the log with: "journalctl -t husarion-depthai" + log_and_echo "Running with options: ${LAUNCH_ARGS}" +fi + +# Run the launch command with the constructed arguments +# ros2 launch teleop_twist_joy teleop-launch.py $LAUNCH_ARGS +ros2 launch $SNAP/usr/bin/joy.launch.py $LAUNCH_ARGS +# ros2 run teleop_twist_joy teleop_node --ros-args -p publish_stamped_twist:=true diff --git a/snap/local/joy_params.yaml b/snap/local/joy_params.yaml index 99dd41d..0ff0bb5 100644 --- a/snap/local/joy_params.yaml +++ b/snap/local/joy_params.yaml @@ -1,4 +1,6 @@ -joy_node: +# joy_node: +--- +/**: ros__parameters: dev: "/dev/input/js0" # Replace with your joystick device deadzone: 0.1 diff --git a/snap/local/joy_teleop.config.yaml b/snap/local/joy_teleop.config.yaml index a8783a6..be69fff 100644 --- a/snap/local/joy_teleop.config.yaml +++ b/snap/local/joy_teleop.config.yaml @@ -22,5 +22,6 @@ yaw: 0.4 require_enable_button: true - enable_button: 4 # TL shoulder button - enable_turbo_button: -1 # disabled \ No newline at end of file + enable_button: 4 # LB button + enable_turbo_button: 7 + publish_stamped_twist: true \ No newline at end of file diff --git a/snap/local/launcher.sh b/snap/local/launcher.sh index 7c8fe1e..d137056 100755 --- a/snap/local/launcher.sh +++ b/snap/local/launcher.sh @@ -35,7 +35,7 @@ if [ "${VALUE}" == "basic" ]; then ros2 launch rosbot_xl_bringup bringup.launch.py ${LAUNCH_OPTIONS} elif [ "${VALUE}" == "manipulation" ]; then # Check if SERIAL_PORT is set to auto or specified - SERIAL_PORT=$(find_ttyUSB driver.manipulator-serial-port "0403" "6014") + SERIAL_PORT=$(find_usb_device "ttyUSB" driver.manipulator-serial-port "0403" "6014") if [ $? -ne 0 ]; then log_and_echo "Failed to find the serial port." exit 1 diff --git a/snap/local/local-ros/check_daemon_running.sh b/snap/local/local-ros/check_daemon_running.sh deleted file mode 100755 index cbe1590..0000000 --- a/snap/local/local-ros/check_daemon_running.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash -e - -# Define a function to log and echo messages -source $SNAP/usr/bin/utils.sh - -if snapctl services ${SNAP_NAME}.daemon | grep -qw active; then - log_and_echo "to run ${SNAP_NAME} snap interactively, you need to stop the daemon first, run:" - log_and_echo "sudo ${SNAP_NAME}.stop" - exit 1 -fi - -exec $@ \ No newline at end of file diff --git a/snap/local/local-ros/configure_hook_ros.sh b/snap/local/local-ros/configure_hook_ros.sh deleted file mode 100755 index 9104b2b..0000000 --- a/snap/local/local-ros/configure_hook_ros.sh +++ /dev/null @@ -1,176 +0,0 @@ -#!/bin/bash -e - -# The configure hook is called every time one the following actions happen: -# - initial snap installation -# - snap refresh -# - whenever the user runs snap set|unset to change a configuration option - -# Define a function to log and echo messages -source $SNAP/usr/bin/utils.sh - -# Function to check the type of the provided XML file -check_xml_profile_type() { - local xml_file="$1" - - if [[ ! -f "$xml_file" ]]; then - log_and_echo "File '$xml_file' does not exist." - return 1 - fi - - local root_element - local namespace - - # Extract the root element - root_element=$(yq '. | keys | .[1]' "$xml_file") - - # Extract the namespace based on the root element - if [[ "$root_element" == "CycloneDDS" ]]; then - namespace=$(yq .CycloneDDS."+@xmlns" "$xml_file") - elif [[ "$root_element" == "profiles" ]]; then - namespace=$(yq .profiles."+@xmlns" "$xml_file") - else - namespace="unknown" - fi - - # Remove quotes from the extracted values - root_element=${root_element//\"/} - namespace=${namespace//\"/} - - if [[ "$root_element" == "profiles" ]] && [[ "$namespace" == "http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles" ]]; then - echo "rmw_fastrtps_cpp" - elif [[ "$root_element" == "CycloneDDS" ]] && [[ "$namespace" == "https://cdds.io/config" ]]; then - echo "rmw_cyclonedds_cpp" - else - exit 1 - fi -} - -VALID_ROS_KEYS=("localhost-only" "domain-id" "transport" "namespace") - -# Call the validation function -validate_keys "ros" VALID_ROS_KEYS[@] - -ROS_LOCALHOST_ONLY="$(snapctl get ros.localhost-only)" -ROS_DOMAIN_ID="$(snapctl get ros.domain-id)" - -# Make sure ROS_LOCALHOST_ONLY is valid -VALID_ROS_LOCALHOST_ONLY_OPTIONS=(1 0) -validate_option "ros.localhost-only" VALID_ROS_LOCALHOST_ONLY_OPTIONS[@] - -# Make sure ROS_DOMAIN_ID is valid -# Make sure WEBUI_PORT is valid -SUPPORTED_RANGE=(0 232) -# Validate a specific port, for example, webui.port -validate_number "ros.domain-id" SUPPORTED_RANGE[@] - -# Get the ros.transport setting using snapctl -OPT="ros.transport" -TRANSPORT_SETTING="$(snapctl get ${OPT})" - -# Check if TRANSPORT_SETTING is "builtin" -if [ "$TRANSPORT_SETTING" == "builtin" ]; then - # Change the value to "rmw_fastrtps_cpp" - TRANSPORT_SETTING="rmw_fastrtps_cpp" -fi - -# Only exit with status 1 if conditions are not met -if [ "$TRANSPORT_SETTING" != "rmw_fastrtps_cpp" ] && [ "$TRANSPORT_SETTING" != "rmw_cyclonedds_cpp" ] && [ ! -f "${SNAP_COMMON}/${TRANSPORT_SETTING}.xml" ]; then - log_and_echo "'${SNAP_COMMON}/${TRANSPORT_SETTING}.xml' does not exist." - exit 1 -fi - -if [ "$TRANSPORT_SETTING" = "rmw_fastrtps_cpp" ] || [ "$TRANSPORT_SETTING" = "shm" ]; then - if ! snapctl is-connected shm-plug; then - log_and_echo "to use 'rmw_fastrtps_cpp' and 'shm' tranport shm-plug need to be connected, please run:" - log_and_echo "sudo snap connect ${SNAP_NAME}:shm-plug ${SNAP_NAME}:shm-slot" - exit 1 - fi -fi - -# # Make sure ros-humble-ros-base is connected -# ROS_PLUG="ros-humble-ros-base" - -# if ! snapctl is-connected ${ROS_PLUG}; then -# log_and_echo "Plug '${ROS_PLUG}' isn't connected. Please run:" -# log_and_echo "snap connect ${SNAP_NAME}:${ROS_PLUG} ${ROS_PLUG}:${ROS_PLUG}" -# exit 1 -# fi - -# Create the ${SNAP_COMMON}/ros.env file and export variables (for bash session running ROS2) -ROS_ENV_FILE="${SNAP_COMMON}/ros.env" - -# Create the ${SNAP_COMMON}/ros.env file and export variables (for bash session running ROS2) -ROS_SNAP_ARGS="${SNAP_COMMON}/ros_snap_args" - -echo "export ROS_DOMAIN_ID=${ROS_DOMAIN_ID}" > "${ROS_ENV_FILE}" -echo "export ROS_LOCALHOST_ONLY=${ROS_LOCALHOST_ONLY}" >> "${ROS_ENV_FILE}" - -NAMESPACE=$(snapctl get ros.namespace) - -# Check if the namespace is set and not empty -if [ -n "$NAMESPACE" ]; then - echo "ros.domain-id=${ROS_DOMAIN_ID} ros.localhost-only=${ROS_LOCALHOST_ONLY} ros.transport=${TRANSPORT_SETTING} ros.namespace=${NAMESPACE}" > "${ROS_SNAP_ARGS}" - echo "export ROS_NAMESPACE=${NAMESPACE}" >> "${ROS_ENV_FILE}" -else - echo "ros.domain-id=${ROS_DOMAIN_ID} ros.localhost-only=${ROS_LOCALHOST_ONLY} ros.transport=${TRANSPORT_SETTING} ros.namespace!" > "${ROS_SNAP_ARGS}" - echo "unset ROS_NAMESPACE" >> "${ROS_ENV_FILE}" -fi - -# Check the ros.transport setting and export the appropriate environment variable -if [ "$TRANSPORT_SETTING" != "rmw_fastrtps_cpp" ] && [ "$TRANSPORT_SETTING" != "rmw_cyclonedds_cpp" ]; then - profile_type=$(check_xml_profile_type "${SNAP_COMMON}/${TRANSPORT_SETTING}.xml") - if [[ "$profile_type" == "rmw_fastrtps_cpp" ]]; then - echo "unset CYCLONEDDS_URI" >> "${ROS_ENV_FILE}" - echo "export RMW_IMPLEMENTATION=${profile_type}" >> "${ROS_ENV_FILE}" - echo "export FASTRTPS_DEFAULT_PROFILES_FILE=${SNAP_COMMON}/${TRANSPORT_SETTING}.xml" >> "${ROS_ENV_FILE}" - elif [[ "$profile_type" == "rmw_cyclonedds_cpp" ]]; then - echo "unset FASTRTPS_DEFAULT_PROFILES_FILE" >> "${ROS_ENV_FILE}" - echo "export RMW_IMPLEMENTATION=${profile_type}" >> "${ROS_ENV_FILE}" - echo "export CYCLONEDDS_URI=file://${SNAP_COMMON}/${TRANSPORT_SETTING}.xml" >> "${ROS_ENV_FILE}" - else - log_and_echo "'${TRANSPORT_SETTING}' is not a supported value for '${OPT}'. Possible values are: rmw_fastrtps_cpp, rmw_cyclonedds_cpp, or a valid profile XML file." - exit 1 - fi -elif [ "$TRANSPORT_SETTING" == "rmw_fastrtps_cpp" ] || [ "$TRANSPORT_SETTING" == "rmw_cyclonedds_cpp" ]; then - echo "unset CYCLONEDDS_URI" >> "${ROS_ENV_FILE}" - echo "unset FASTRTPS_DEFAULT_PROFILES_FILE" >> "${ROS_ENV_FILE}" - echo "export RMW_IMPLEMENTATION=${TRANSPORT_SETTING}" >> "${ROS_ENV_FILE}" -fi - -# Define the path for the manage_ros_env.sh script -MANAGE_SCRIPT="${SNAP_COMMON}/manage_ros_env.sh" - -# Create the manage_ros_env.sh script in ${SNAP_COMMON} -cat << EOF > "${MANAGE_SCRIPT}" -#!/bin/bash - -ROS_ENV_FILE="${SNAP_COMMON}/ros.env" -SOURCE_LINE="source \${ROS_ENV_FILE}" - -add_source_to_bashrc() { - if ! grep -Fxq "\$SOURCE_LINE" ~/.bashrc; then - echo "\$SOURCE_LINE" >> ~/.bashrc - echo "Added '\$SOURCE_LINE' to ~/.bashrc" - else - echo "'\$SOURCE_LINE' is already in ~/.bashrc" - fi -} - -remove_source_from_bashrc() { - sed -i "\|\$SOURCE_LINE|d" ~/.bashrc - echo "Removed '\$SOURCE_LINE' from ~/.bashrc" -} - -case "\$1" in - remove) - remove_source_from_bashrc - ;; - add|*) - add_source_to_bashrc - ;; -esac -EOF - -# Make the manage_ros_env.sh script executable -chmod +x "${MANAGE_SCRIPT}" - diff --git a/snap/local/local-ros/install_hook_ros.sh b/snap/local/local-ros/install_hook_ros.sh deleted file mode 100755 index 86848fb..0000000 --- a/snap/local/local-ros/install_hook_ros.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -e - -# Define a function to log messages -source $SNAP/usr/bin/utils.sh - -snapctl set ros.transport="udp" -snapctl set ros.localhost-only=0 -snapctl set ros.domain-id=0 -snapctl set ros.namespace! # unset - -if ! snapctl is-connected ros-humble-ros-base; then - log "Plug 'ros-humble-ros-base' isn't connected, please run:" - log "sudo snap connect ${SNAP_NAME}:ros-humble-ros-base ros-humble-ros-base:ros-humble-ros-base" -fi - -if ! snapctl is-connected shm-plug; then - log "Plug 'shm-plug' isn't connected, please run:" - log "sudo snap connect ${SNAP_NAME}:shm-plug ${SNAP_NAME}:shm-slot" -fi - -# copy DDS config files to shared folder -cp -r $SNAP/usr/share/${SNAP_NAME}/config/*.xml ${SNAP_COMMON}/ \ No newline at end of file diff --git a/snap/local/local-ros/ros_setup.sh b/snap/local/local-ros/ros_setup.sh deleted file mode 100755 index 2fffe43..0000000 --- a/snap/local/local-ros/ros_setup.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -e - -source $SNAP_COMMON/ros.env - -exec $@ \ No newline at end of file diff --git a/snap/local/local-ros/shm.xml b/snap/local/local-ros/shm.xml deleted file mode 100644 index 4f2910f..0000000 --- a/snap/local/local-ros/shm.xml +++ /dev/null @@ -1,18 +0,0 @@ - -