Repository navigation
ui: load the robot description from platform-sw; start the battery node - #25
Merged
Merged
Conversation
- Remove the copied robo_urdf.urdf.xacro, gazebo_control.xacro and their 12 STL meshes (byte-identical to platform-sw). Flask now xacro-processes and serves openamrobot_description from openamr-platform-sw (REP 105 base frames and 2.0 sensor frames, platform-sw PR #55), resolved per request so the UI still starts when the package is absent. - package.xml: exec_depend openamrobot_description. docs/installation.md records the validated platform-sw commit 174731c and the rosdep skip key. - battery.py: console_scripts entry point "battery"; serial port is a parameter with no default (never opens /dev/ttyUSB0, commonly the RPLIDAR); simulated fallback when no port is set. Started from new_ui_launch.py only with start_battery_monitor:=true. Comment: on 2.0 battery state comes from the base controller; serial is Gate A legacy. - Docs: lesson 05 launch path, lesson 06 model frames, READMEs, model unavailable hint. - Tests: description served from platform-sw, unavailable when missing, path traversal rejected; battery never opens serial without a port. Source: openamr-platform-sw main, P-03 rev19.0 item 19. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EwTn5mzG9oyoqiv9HiDdTP Signed-off-by: Alex Reznichenko <info@botshare.ai>
- Dockerfile: fetch openAMRobot/openamr-platform-sw at the pinned commit 174731c6a593870276fa47d8f92db2ef79eda79a (OPENAMR_PLATFORM_SW_COMMIT build arg, checked after fetch), colcon build openamrobot_description only into /opt/openamr_platform_sw, and record the commit in PLATFORM_SW_COMMIT. git added to the apt layer. - container_entrypoint.sh: source the platform-sw workspace before the UI workspace. Also relax nounset only while sourcing setup scripts: with the current ros:jazzy-ros-base, /opt/ros/jazzy/setup.bash reads the unset AMENT_TRACE_SETUP_FILES and the main-branch entrypoint exited before the UI started. - README: note the image builds the description at the pinned commit. Verified in the built container: manifest available, /api/robot-description/urdf 200 with base_footprint root and the 2.0 sensor frames, base_link.STL 200 and byte-identical to the pinned platform-sw install. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EwTn5mzG9oyoqiv9HiDdTP Signed-off-by: Alex Reznichenko <info@botshare.ai>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull request
Source: openamr-platform-sw main, P-03 rev19.0 item 19.
Change, scope and decisions taken in this session
main@8b981adde859f97531561dec34adb52ff39be579; headdescription-from-platform-sw@a9a45d9490ed803419705d5265f0cf0a75ab2347. Two commits, both DCO signed off:d312d3e(description and battery) anda9a45d9(Docker).main@174731c6a593870276fa47d8f92db2ef79eda79a. It contains PR ui: read-only upper-body view on the Robot Description page (prototype) #55 (935efc7) and PR [integration candidate, do not merge] rc.1 UI stack #56 (174731c). PR [integration candidate, do not merge] rc.1 UI stack #56 changes comments only: it marks the 0.400 m track as a placeholder.flask_app.py):/api/robot-description/{manifest,urdf,assets}now resolve the installedopenamrobot_descriptionshare directory per request throughget_package_share_directory.openamr_ui_package/robot_description/is removed, not only the two xacro files.cmp).setup.pyinstall entry for the folder is removed.docs/installation.mdnow records the validated commit174731c. That is the existing "pin as deployment configuration" convention, so no.reposfile is added.package.xmlgainsexec_depend openamrobot_description.--skip-keys openamrobot_description, because the package is not in rosdistro.a9a45d9):Dockerfilefetches openamr-platform-sw at the pinned commit (build argOPENAMR_PLATFORM_SW_COMMIT=174731c6...) and checks that the fetched HEAD equals it.openamrobot_descriptioninto/opt/openamr_platform_swand records the commit in/opt/openamr_platform_sw/PLATFORM_SW_COMMIT.gitis added to the apt layer.scripts/container_entrypoint.shsources that workspace before the UI workspace.ros:jazzy-ros-base(digest066420e0),main's entrypoint exits before the UI starts. Itsset -uis active while/opt/ros/jazzy/setup.bashreads the unsetAMENT_TRACE_SETUP_FILES. The entrypoint now relaxesnounsetonly while sourcing setup scripts.camera_link: no UI code consumes it. platform-sw still publishes it (legacy IMX708, Gate A) and the served URDF contains it.ros2 launch openamr_ui_bringup ui.launch.py start_battery_monitor:=true. The default isfalse.portparameter (launch argbattery_port), with no default. Without it the node never opens a serial device and publishes the simulated value. A named port that fails to open also falls back to the simulated value.battery.pyhard-coded/dev/ttyUSB0at 9600 baud. The RPLIDAR is a CP2102 device, and the platform-sw drivers README uses it withlidar_port:=/dev/ttyUSB0. Opening that port from the UI would reconfigure and read the lidar's line.setup.pygains the console scriptbattery.base_footprintroot;base_linkat the drive axle, 0.098 m up;lidar_link(0.330, 0, 0.124) with yaw pi; base camera Gemini 336L (base_camera_link); legacycamera_link;imu_link; 4 ultrasonic and 2 ToF frames.static/appbundle is not re-synced.Safety impact
/dev/ttyUSB0implicitly.start_battery_monitor:=trueis set without a port, the value is simulated, and the node says so in its log.Validation (local, in this cloud session)
Environment: Ubuntu 24.04, Node v20.20.2, ROS 2 Jazzy, Python 3.12.3. The platform-sw
openamrobot_descriptionpackage at174731cwas built into a separate overlay and sourced before the UI workspace.cd web && npm cicd web && CI=true npm test -- --watchAll=falsemainhas 0 web test files. Not a pass. Hosted CI runs this with--passWithNoTests.cd web && npm run buildsource /opt/ros/jazzy/setup.bash, source the overlay, thenpython3.12 -m colcon build --symlink-install(clean build)python3.12 -m colcon test --packages-select openamr_ui_package openamr_ui_msgs && python3.12 -m colcon test-result --verbosetest/test_description_and_battery.pyall ran and passed, none skipped, because the description package was sourced.python3 tools/watchdog.py --root <clone> --report-only(openAMRobot/.githubmain@13796dc; the clone directory is namedopenamrobot-ui)New tests:
base_footprint,base_link,lidar_link,base_camera_link,camera_link,imu_link, the fourus_*frames and the twotof_*frames, and a mesh from the platform-sw share.serial.Serialwithout a port.batteryentry point is registered.Deliberate broken variants (each run, then restored byte-for-byte):
battery.pydefault port set back to/dev/ttyUSB0test_no_port_never_opens_serial_and_publishes_simulatedtest_asset_path_traversal_is_rejected. Without the check, the running app returned 200 and served/etc/hostname, so the check is load-bearing.Headless launch: the repository has no launch test (no
launch_testing), so the UI launch path was run headless by hand withros2 launch openamr_ui_bringup ui.launch.py./ui/flask_app,/ui/map_volatile_relayand/ui/nav_relaysstart, and no battery node starts."available": true./urdfreturns the platform-sw URDF with 25 links.base_link.STLreturns 200 (12379084 bytes).start_battery_monitor:=true:battery_monitorruns withportset to an empty string and logs the SIMULATED warning.ros2 topic echo --once /battery_statusreturneddata: 99.83.KeyboardInterruptfrom the SIGINT sent to stop the run, which is existing node behaviour.Docker check (image built from the committed
Dockerfileata9a45d9):The build ran in this session's local Docker daemon:
<session base>isros:jazzy-ros-base(digest066420e0) plus this sandbox's egress proxy CA and CA env vars. That base is session-local only and is not part of this PR; it was needed only because this sandbox reaches GitHub and npm through a proxy. The committedDockerfilewas used unchanged.174731c, the HEAD check passed, andopenamrobot_descriptionbuilt ("1 package finished")./opt/openamr_platform_sw/PLATFORM_SW_COMMIT=174731c6a593870276fa47d8f92db2ef79eda79a;urdf/containsrobo_urdf.urdf.xacro,gazebo_control.xacroandrobot.sdf; there are 12 visual meshes; norobot_descriptioncopy is in the UI install.docker run --network host, image's own entrypoint, as indocker-compose.yml):map_relay,nav_relay,flask,rosbridge_websocket,rosapi_nodeandweb_video_server.docker exec ... curlinside the container:GET /api/robot-description/manifestreturns"available": trueand"package": "openamrobot_description".GET /api/robot-description/urdfreturns HTTP 200 with 25 links and rootbase_footprint. It containsbase_footprint_joint(0, 0, 0.098),lidar_joint(0.330, 0, 0.124, yaw pi),base_camera_joint(0.376, 0, 0.0445, pitch -0.1745 with the defaultbt10),camera_link,imu_link,us_front_left,us_front_right,us_rear_left,us_rear_right,tof_frontandtof_rear.GET /api/robot-description/assets/meshes/visual/base_link.STLreturns HTTP 200,model/stl, 12379084 bytes. Its sha256 equals the pinned platform-sw install file (dfedb492ae1b6ca8...)./etc/passwdreturns 404.GET /robot(SPA route) returns 200.main's unchangedscripts/container_entrypoint.sh, run in the same image, and a plainros:jazzy-ros-basewithset -euo pipefail; source /opt/ros/jazzy/setup.bash, both fail with/opt/ros/jazzy/setup.bash: line 8: AMENT_TRACE_SETUP_FILES: unbound variable. The first run of the new image failed the same way. After theset +u/set -uchange, the container starts, as shown above.Container notes: this session container's
python3is 3.11, so colcon andros2were run withpython3.12.python3-flaskandpython3-serial(both declaredexec_depend) were installed from Ubuntu apt into the session container only.Informational lint (repository flake8 is skipped): the touched Python files add no new non-quote flake8 findings. One I100 import-order finding in
flask_app.pyalready existed onmainand now shows the changed import text.Hosted checks: see the CI results on this PR. They are separate from the local results above. Hosted CI builds neither ROS nor the Docker image, so the colcon and Docker results above are local only.
Not verified
main. It was written as given and is not verified against a source.openamrobot_docking bringup_sim.launch.py) and the browser rendering of the Robot page were not run. Only the HTTP API and node startup were checked.static/appbundle inros2/was not re-synced, so the updated "model unavailable" hint takes effect only after the next frontend sync.main, so it is not evidence of any web behaviour.Dependencies and licences
openamrobot_description(openamr-platform-sw, MIT per itssetup.py), at the validated commit recorded indocs/installation.mdand theDockerfile.gitpackage and fetches openamr-platform-sw from GitHub at build time.AI disclosure
This change was written with material AI assistance (Claude Code), under the author's direction. That covers the code, tests, docs, the commit messages and this PR text. No third-party code was added.
Contribution terms
Signed-off-byfor the session's verified git identity, as authorized by the author.license/clastatus is reported on this PR.Intellectual property and provenance
🤖 Generated with Claude Code
https://claude.ai/code/session_01EwTn5mzG9oyoqiv9HiDdTP