Skip to content
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
92b620a
add s6 agent for system manager
GyuH13 Jan 8, 2026
af1de2f
chore: update Dockerfiles to install setuptools with no-cache and adj…
GyuH13 Jan 8, 2026
a735b7e
change location of socket volume mapping
GyuH13 Jan 9, 2026
cca8ee9
refactor: update Dockerfiles to copy system_manager directly and inst…
GyuH13 Jan 9, 2026
59d4a36
fix: update physical_ai_server image to use system-manager-dev for de…
GyuH13 Jan 9, 2026
5929d99
chore: add common service directory and update PYTHONPATH in ros2_ser…
GyuH13 Jan 9, 2026
833dbe6
chore: add physical_ai_server-pipeline to s6 user bundle in Dockerfiles
GyuH13 Jan 9, 2026
43461d0
remove system manager
GyuH13 Jan 12, 2026
ae15064
refactor: replace system_manager with robotis_system_manager in Docke…
GyuH13 Jan 19, 2026
43aa49a
rm system manager folder
GyuH13 Jan 19, 2026
eb58ac6
Merge branch 'main' of https://github.com/ROBOTIS-GIT/physical_ai_too…
GyuH13 Feb 6, 2026
d43b3f1
Update Dockerfile.arm64 to clone robotis_system_manager repository an…
GyuH13 Feb 6, 2026
9d66e30
change name to talos
GyuH13 Feb 6, 2026
fe80d65
Refactor Docker setup by removing unused s6 services and updating s6-…
GyuH13 Feb 6, 2026
aa9d982
Update Docker Compose configuration to use the latest image for the p…
GyuH13 Feb 6, 2026
f4bf99a
bump
GyuH13 Feb 6, 2026
86402d9
Add RMW_IMPLEMENTATION logging to ros2_service_run.sh for improved se…
GyuH13 Feb 6, 2026
aabfb8a
change shell
GyuH13 Feb 10, 2026
b918ec9
change check process function
GyuH13 Feb 10, 2026
09e9942
delete comments
GyuH13 Feb 10, 2026
178b45b
remove set -e in finish script
GyuH13 Feb 10, 2026
79d9c96
remove log-prepare folder
GyuH13 Feb 10, 2026
0acd2d6
docker arm64
GyuH13 Feb 10, 2026
1567dcb
remove gpg key error avoidance line
GyuH13 Feb 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ services:
- ./huggingface:/root/.cache/huggingface
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- /var/run/robotis/agent_sockets/physical_ai_server:/var/run/agent
privileged: true
command: bash
runtime: nvidia
deploy:
resources:
Expand Down
1 change: 1 addition & 0 deletions docker/s6-agent/dependencies
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

9 changes: 9 additions & 0 deletions docker/s6-agent/finish
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/with-contenv sh
# Agent service finish script
# Cleanup when service stops

# Remove socket file if it exists
[ -S /var/run/agent/s6_agent.sock ] && rm -f /var/run/agent/s6_agent.sock

exit 0

14 changes: 14 additions & 0 deletions docker/s6-agent/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/command/with-contenv sh
# Agent service run script
# This script starts the s6-agent FastAPI service

set -e

# Ensure socket directory exists
mkdir -p /var/run/agent
chmod 777 /var/run/agent

# Start uvicorn with Unix Domain Socket
# The agent is part of talos package
exec uvicorn talos.agent.s6_agent:app --uds /var/run/agent/s6_agent.sock --log-level info

2 changes: 2 additions & 0 deletions docker/s6-agent/type
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
longrun

62 changes: 62 additions & 0 deletions docker/s6-services/common/ros2_service_finish.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/command/with-contenv sh
# Reusable ROS2 service finish script template
# This script runs when the service is stopped.
# Usage: SERVICE_NAME=<name> /path/to/ros2_service_finish.sh [exit_code]

set -e

# Service name must be provided via environment variable
SERVICE_NAME="${SERVICE_NAME}"
if [ -z "${SERVICE_NAME}" ]; then
echo "Error: SERVICE_NAME environment variable must be set" >&2
exit 1
fi

# Log the finish event for debugging
EXIT_CODE=${1:-unknown}
echo "[${SERVICE_NAME} finish] Service stopped with exit code $EXIT_CODE"

# If we recorded a process group ID, send a final graceful SIGTERM to that group
# and wait until the processes are fully dead (or a timeout is reached).
PGID_FILE=/run/${SERVICE_NAME}.pgid
if [ -f "${PGID_FILE}" ]; then
PGID=$(cat "${PGID_FILE}" 2>/dev/null || echo "")
if [ -n "${PGID}" ]; then
echo "[${SERVICE_NAME} finish] Sending SIGTERM to process group ${PGID}"
# Negative PGID means "entire process group" to kill(2)
kill -TERM -"${PGID}" 2>/dev/null || echo "[${SERVICE_NAME} finish] Warning: kill -TERM -${PGID} failed or group already gone"

# Wait until the process group is gone, with a hard timeout
TIMEOUT=30 # total seconds to wait
SLEEP_INTERVAL=1 # seconds between checks
ELAPSED=0

# Helper: returns 0 if PGID still has processes, 1 otherwise
pgid_alive() {
# 'ps -o pgid=' prints the PGID for each matching process;
# if there is at least one line, the group is still alive.
ps -o pgid= -g "${PGID}" 2>/dev/null | grep -q .
}

if pgid_alive; then
echo "[${SERVICE_NAME} finish] Waiting for process group ${PGID} to exit (timeout: ${TIMEOUT}s)..."
fi

while pgid_alive && [ "${ELAPSED}" -lt "${TIMEOUT}" ]; do
sleep "${SLEEP_INTERVAL}"
ELAPSED=$((ELAPSED + SLEEP_INTERVAL))
done

if pgid_alive; then
echo "[${SERVICE_NAME} finish] Timeout waiting for process group ${PGID} to exit; sending SIGKILL"
kill -KILL -"${PGID}" 2>/dev/null || echo "[${SERVICE_NAME} finish] Warning: kill -KILL -${PGID} failed or group already gone"
else
echo "[${SERVICE_NAME} finish] Process group ${PGID} fully exited after ${ELAPSED}s"
fi
fi
fi

echo "[${SERVICE_NAME} finish] Finish script completed"

exit 0

60 changes: 60 additions & 0 deletions docker/s6-services/common/ros2_service_run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/bin/bash
# Reusable ROS2 service run script template
# This script launches ROS2 commands for any service
# Usage:
# SERVICE_NAME=<name> ROS2_COMMAND="<full command>" /path/to/ros2_service_run.sh
# If ROS2_COMMAND is not set, defaults to: ros2 launch physical_ai_server ${SERVICE_NAME}.launch.py
# Note: This script is called via /command/with-contenv, so environment is already set up

set -e

# Service name must be provided via environment variable
SERVICE_NAME="${SERVICE_NAME}"
if [ -z "${SERVICE_NAME}" ]; then
echo "Error: SERVICE_NAME environment variable must be set" >&2
exit 1
fi

# Set ROS_DOMAIN_ID if not already set (default to 30)
export ROS_DOMAIN_ID=${ROS_DOMAIN_ID:-30}
export ROS_DISTRO=${ROS_DISTRO:-jazzy}
export COLCON_WS=${COLCON_WS:-/root/ros2_ws}
export PATH=/opt/venv/bin:${PATH}
export PYTHONPATH=/opt/venv/lib/python3.12/site-packages:${PYTHONPATH}
export PYTHONPATH=${COLCON_WS}/src/physical_ai_tools/lerobot/src:${PYTHONPATH}

# Enable s6-overlay debug logging (set S6_VERBOSITY=1 for more verbose output)
export S6_VERBOSITY=${S6_VERBOSITY:-1}

echo "[${SERVICE_NAME}] Starting service..."
echo "[${SERVICE_NAME}] ROS_DOMAIN_ID=${ROS_DOMAIN_ID}"
echo "[${SERVICE_NAME}] ROS_DISTRO=${ROS_DISTRO}"
echo "[${SERVICE_NAME}] RMW_IMPLEMENTATION=${RMW_IMPLEMENTATION}"
echo "[${SERVICE_NAME}] COLCON_WS=${COLCON_WS}"
echo "[${SERVICE_NAME}] PID: $$"

# Record process group ID so the finish script can target the whole group
PGID=$(ps -o pgid= -p $$ | tr -d ' ')
echo "[${SERVICE_NAME}] Process group: ${PGID}"
echo "${PGID}" > /run/${SERVICE_NAME}.pgid || true

# Source ROS2 environment
source /opt/ros/${ROS_DISTRO}/setup.bash
source ${COLCON_WS}/install/setup.bash

# Determine the command to execute
# If ROS2_COMMAND is set, use it; otherwise, use the default launch command
if [ -n "${ROS2_COMMAND}" ]; then
ROS2_CMD="${ROS2_COMMAND}"
echo "[${SERVICE_NAME}] Executing custom command: ${ROS2_CMD}"
else
ROS2_CMD="ros2 launch physical_ai_server ${SERVICE_NAME}.launch.py"
echo "[${SERVICE_NAME}] Executing default command: ${ROS2_CMD}"
fi

# Execute the ROS2 command
# Using 'exec' ensures the command becomes PID 1 of this service,
# which allows s6 to properly signal it and its children
# Note: stdout/stderr are automatically piped to ${SERVICE_NAME}-log via producer-for/consumer-for
exec bash -c "${ROS2_CMD}"

3 changes: 3 additions & 0 deletions docker/s6-services/physical_ai_server-log-prepare/type
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
oneshot


3 changes: 3 additions & 0 deletions docker/s6-services/physical_ai_server-log-prepare/up
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
if { mkdir -p /var/log/physical_ai_server }
if { chown nobody:nogroup /var/log/physical_ai_server }
chmod 02755 /var/log/physical_ai_server
3 changes: 3 additions & 0 deletions docker/s6-services/physical_ai_server-log/consumer-for
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
physical_ai_server


3 changes: 3 additions & 0 deletions docker/s6-services/physical_ai_server-log/pipeline-name
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
physical_ai_server-pipeline


7 changes: 7 additions & 0 deletions docker/s6-services/physical_ai_server-log/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/command/with-contenv sh
# Logging service for physical_ai_server
# Uses logutil-service which wraps s6-log with proper configuration

exec logutil-service /var/log/physical_ai_server


3 changes: 3 additions & 0 deletions docker/s6-services/physical_ai_server-log/type
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
longrun


2 changes: 2 additions & 0 deletions docker/s6-services/physical_ai_server/dependencies
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@


19 changes: 19 additions & 0 deletions docker/s6-services/physical_ai_server/finish
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/command/with-contenv sh
# Physical AI Server service finish script
# Uses reusable ROS2 service template

set -e

SERVICE_NAME="physical_ai_server"
COMMON_SCRIPT="/usr/local/lib/s6-services/ros2_service_finish.sh"

if [ -f "${COMMON_SCRIPT}" ]; then
# Use env to explicitly pass variables to the script
# The with-contenv wrapper will preserve these variables
exec /command/with-contenv env SERVICE_NAME="${SERVICE_NAME}" sh "${COMMON_SCRIPT}" "$@"
else
echo "Error: Common script not found at ${COMMON_SCRIPT}" >&2
exit 1
fi


3 changes: 3 additions & 0 deletions docker/s6-services/physical_ai_server/producer-for
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
physical_ai_server-log


23 changes: 23 additions & 0 deletions docker/s6-services/physical_ai_server/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/command/with-contenv bash
# Physical AI Server service run script
# Uses reusable ROS2 service template

set -e

SERVICE_NAME="physical_ai_server"
ROS2_COMMAND="ros2 launch physical_ai_server physical_ai_server_bringup.launch.py"
COMMON_SCRIPT="/usr/local/lib/s6-services/ros2_service_run.sh"

if [ -f "${COMMON_SCRIPT}" ]; then
export SERVICE_NAME="${SERVICE_NAME}"
export ROS2_COMMAND="${ROS2_COMMAND}"
# Use env to explicitly pass variables to the script
# The with-contenv wrapper will preserve these variables
exec /command/with-contenv env SERVICE_NAME="${SERVICE_NAME}" ROS2_COMMAND="${ROS2_COMMAND}" bash "${COMMON_SCRIPT}"
else
# Fallback if common script not available
echo "Error: Common script not found at ${COMMON_SCRIPT}" >&2
exit 1
fi


3 changes: 3 additions & 0 deletions docker/s6-services/physical_ai_server/type
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
longrun


4 changes: 4 additions & 0 deletions physical_ai_bt/CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
Changelog for package physical_ai_bt
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

0.8.1 (2026-02-06)
------------------
* None

0.8.0 (2026-01-19)
------------------
* Initial release of physical_ai_bt package
Expand Down
2 changes: 1 addition & 1 deletion physical_ai_bt/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>physical_ai_bt</name>
<version>0.8.0</version>
<version>0.8.1</version>
<description>
Python-based Behavior Tree for Physical AI
</description>
Expand Down
2 changes: 1 addition & 1 deletion physical_ai_bt/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

setup(
name=package_name,
version='0.8.0',
version='0.8.1',
packages=find_packages(),
data_files=[
('share/ament_index/resource_index/packages', ['resource/' + package_name]),
Expand Down
4 changes: 4 additions & 0 deletions physical_ai_interfaces/CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
Changelog for package physical_ai_interfaces
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

0.8.1 (2026-02-06)
------------------
* None

0.8.0 (2026-01-19)
------------------
* None
Expand Down
2 changes: 1 addition & 1 deletion physical_ai_interfaces/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>physical_ai_interfaces</name>
<version>0.8.0</version>
<version>0.8.1</version>
<description>
ROS 2 interfaces for Physical AI tools
</description>
Expand Down
4 changes: 4 additions & 0 deletions physical_ai_manager/CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
Changelog for package physical_ai_manager
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

0.8.1 (2026-02-06)
------------------
* None

0.8.0 (2026-01-19)
------------------
* None
Expand Down
4 changes: 2 additions & 2 deletions physical_ai_manager/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion physical_ai_manager/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "physical_ai_manager",
"version": "0.8.0",
"version": "0.8.1",
"description": "Web UI for Physical AI Platform",
"author": "Kiwoong Park <pkw@robotis.com>",
"contributors": [
Expand Down
5 changes: 5 additions & 0 deletions physical_ai_server/CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
Changelog for package physical_ai_server
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

0.8.1 (2026-02-06)
------------------
* Add s6-agent and s6-services for supporting talos system manager
* Contributors: Hyungyu Kim

0.8.0 (2026-01-19)
------------------
* None
Expand Down
Loading
Loading