Animated robot expression interface as lightweight web application: **Architecture:** - HTML5 Canvas rendering engine - Node.js HTTP server (localhost:3000) - ROSLIB WebSocket bridge for ROS2 topics - Fullscreen responsive design (1024×600) **Features:** - 8 emotional states (happy, alert, confused, sleeping, excited, emergency, listening, talking) - Real-time ROS2 subscriptions: - /saltybot/state (emotion triggers) - /saltybot/battery (status display) - /saltybot/target_track (EXCITED emotion) - /saltybot/obstacles (ALERT emotion) - /social/speech/is_speaking (TALKING emotion) - /social/speech/is_listening (LISTENING emotion) - Tap-to-toggle status overlay - 60fps Canvas animation on Wayland - ~80MB total memory (Node.js + browser) **Files:** - public/index.html — Main page (1024×600 fullscreen) - public/salty-face.js — Canvas rendering + ROS2 integration - server.js — Node.js HTTP server with CORS support - systemd/salty-face-server.service — Auto-start systemd service - docs/SALTY_FACE_WEB_APP.md — Complete setup & API documentation **Integration:** - Runs in Chromium kiosk (Issue #374) - Depends on rosbridge_server for WebSocket bridge - Serves on localhost:3000 (configurable) **Next:** Issue #371 (Accessibility enhancements) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
43 lines
818 B
Desktop File
43 lines
818 B
Desktop File
[Unit]
|
|
Description=SaltyFace Web App Server (Node.js)
|
|
Documentation=https://github.com/saltytech/saltylab-firmware/issues/370
|
|
After=network.target
|
|
Before=chromium-kiosk.service
|
|
Requires=chromium-kiosk.service
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=orin
|
|
Group=nogroup
|
|
WorkingDirectory=/opt/saltybot/app
|
|
|
|
# Node.js server
|
|
ExecStart=/usr/bin/node server.js --port 3000 --host 0.0.0.0
|
|
|
|
# Environment
|
|
Environment="NODE_ENV=production"
|
|
Environment="NODE_OPTIONS=--max-old-space-size=256"
|
|
|
|
# Restart policy
|
|
Restart=on-failure
|
|
RestartSec=3s
|
|
|
|
# Resource limits
|
|
MemoryMax=256M
|
|
CPUQuota=50%
|
|
|
|
# Logging
|
|
StandardOutput=journal
|
|
StandardError=journal
|
|
SyslogIdentifier=salty-face-server
|
|
|
|
# Security
|
|
NoNewPrivileges=true
|
|
PrivateTmp=true
|
|
ProtectSystem=strict
|
|
ProtectHome=yes
|
|
ReadWritePaths=/opt/saltybot/logs
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|