A web application for controlling ROS 2 robots, featuring a React frontend, ROS 2 integration via rosbridge, and secure local development setup with Caddy and HTTPS. Inspired by retro handheld consoles.
- ๐ฑ Responsive design for desktop and mobile
- ๐ ROS 2 connection (via rosbridge)
- ๐ท Camera stream display (via web_video_server)
- ๐น๏ธ Interchangeable control interfaces:
- ๐ Drone control pad for aerial vehicles
- ๐ฆพ Manipulator control for robotic arms
- And many more than you can create!
- ๐ง 3D visualization support
- ๐จ Customizable themes with user-created color palettes
roboboy_1080p.webm
๐ Prerequisites
- Docker and Docker Compose installed.
- mkcert for local HTTPS setup.
โ๏ธ Local Development Setup
-
Clone the Repository:
git clone [email protected]:tessel-la/robo-boy.git cd robo-boy
-
Setup Local HTTPS with mkcert:
- Install mkcert's CA: Run this once per machine to make browsers trust local certificates.
(You might need
mkcert -install
sudoor administrator privileges) - Create Certificates Directory:
mkdir certs
- Generate Certificate: Replace
YOUR_HOST_IPwith your computer's actual local network IP address (e.g.,192.168.1.67). This certificate will be valid forlocalhostand your IP.mkcert -key-file certs/local-key.pem -cert-file certs/local-cert.pem localhost 127.0.0.1 ::1 YOUR_HOST_IP
- Install mkcert's CA: Run this once per machine to make browsers trust local certificates.
-
Build and Run Services: This command builds the Docker images (if they don't exist or need updating) and starts the
app(React Vite dev server),ros-stack(rosbridge, web_video_server), andcaddy(reverse proxy) containers.docker compose up -d --build
-
Access the Application:
- On your development machine:
https://localhost - From another device on the same network (e.g., mobile):
https://YOUR_HOST_IP(using the same IP you used formkcert)
- On your development machine:
๐ Stopping the Services
# Stop and remove containers
docker compose down
# Stop, remove containers, AND remove Caddy's data volumes (useful for a clean restart)
docker compose down -v The application provides multiple control interfaces that can be swapped during runtime:
๐น๏ธ Pre-built Control Pads
Specialized control interface for aerial vehicles. For testing, use in conjunction with aerial-sim repository.
Interface for controlling robotic arms with precise joint movements. For testing, use in conjunction with manipulator-sim repository.
Additional pre-built interfaces including standard dual-joystick, retro GameBoy-style controls, and voice command interface.
๐ ๏ธ Custom Gamepad Creator
Create your own control interfaces directly in the app! The Custom Gamepad Creator allows you to design personalized control layouts using a drag-and-drop interface.
Features:
- Component Library: Choose from joysticks, buttons, D-pads, toggles, and sliders
- Grid-based Design: Drag and drop components on a customizable grid
- Real-time Preview: Test your gamepad while designing
- ROS Integration: Configure each component to publish to specific ROS topics
- Save & Share: Store layouts locally and export/import via JSON files
Getting Started:
- Click the "+" button in the control panel tabs
- Select "Create Custom Gamepad"
- Drag components from the palette to design your layout
- Configure each component's ROS topic and behavior
- Save your custom gamepad for future use
Perfect for creating specialized control interfaces tailored to your specific robot's needs!
๐ Tab Management
You can open multiple control panels and switch between them with tabs. Mix and match pre-built pads with your custom creations for maximum flexibility.
๐ญ Custom Theme Creator
theme_custom.webm
The application supports multiple themes, including user-created custom themes. Themes define the color palette for the UI elements.
- Access Theme Menu: Click the theme icon button (usually in the bottom-right corner). This opens a popup menu displaying available themes (default and custom).
- Create New Theme: Click the "Create New Theme..." button in the popup. This opens the Theme Creator modal.
- Define Theme:
- Enter a unique Name for your theme.
- Select the base Colors (Primary, Secondary, Background) using the color pickers. Optional colors (Text, Border, etc.) can also be set.
- Choose an Icon to represent your theme in the selector menu.
- Click Save Theme.
- Editing/Deleting: Custom themes will have Edit (pencil) and Delete (trash) icons next to them in the theme selector popup. Clicking Edit opens the Theme Creator pre-filled with that theme's settings. Clicking Delete prompts for confirmation before removing the theme.
โ๏ธ How Theme System Works
- Default themes (
light,dark,solarized) have their CSS variables defined directly insrc/index.cssusing[data-theme="themename"]selectors. - Custom themes are stored in the browser's
localStorage. - When a custom theme is selected, JavaScript dynamically generates a
<style>tag containing CSS variable overrides based on the saved colors and injects it into the document head. The<body>element also gets adata-theme="custom-theme-id"attribute. - UI components should primarily use the defined CSS variables (e.g.,
var(--primary-color),var(--background-color)) for styling to ensure they adapt correctly to the selected theme.
๐ป Development Tips
- Changes to frontend code (in
/src) should trigger hot-reloading in the browser. - If you modify
Dockerfile,docker-compose.yml, orCaddyfile, you'll need to rebuild and restart the services (docker compose up -d --build --force-recreate). - Caddy logs can be viewed with
docker compose logs caddy. - ROS stack logs can be viewed with
docker compose logs ros-stack.
The project is enforcing high code quality standards with strict coverage thresholds (>20% for Statements, Branches, Functions, and Lines).
โ Unit Tests
Unit tests are built with Vitest. They are co-located with source files (e.g., src/hooks/useRos.ts -> src/hooks/useRos.test.ts).
# Run unit tests in watch mode (for development)
npm run test
# Run unit tests once (for CI/CD)
npm run test:run
# Generate coverage report
npm run test:coverage๐ญ End-to-End (E2E) Tests
End-to-End tests are built with Playwright. They verify the full application flow in a real browser environment.
# Run all E2E tests (headless)
npm run e2e
# Run E2E tests with UI runner (interactive debugging)
npm run e2e:ui
# View the last E2E test report
npm run e2e:report๐ Project Structure
The codebase follows a component-based architecture:
/e2e- End-to-End tests (Playwright)app-navigation.spec.ts- Navigation and routing testsentry-page.spec.ts- Entry page interaction tests
/src/components- Main UI components and layouts- Core UI components:
MainControlView,VisualizationPanel,Navbar,SettingsPopup, etc. /gamepads- Pre-built gamepad control interfaces/standard- Standard dual joystick layout/gameboy- GameBoy-style control layout/voice- Voice control interface/drone- Drone control interface/manipulator- Robotic arm control interface/custom- Custom gamepad wrapper component
/visualizers- React wrappers for 3D visualizationPointCloudViz.tsx- Point cloud visualization componentLaserScanViz.tsx- Laser scan visualization componentPoseStampedViz.tsx- Pose/Odometry visualization componentUrdfViz.tsx- URDF model visualization componentCameraInfoViz.tsx- Camera information display
- Core UI components:
/src/features- Feature-specific code organized by functionality/theme- Theme system with custom color palette creation/customGamepad- Custom Gamepad Creator Systemtypes.ts- TypeScript interfaces and component definitionsdefaultLayouts.ts- Pre-built layouts and component librarygamepadStorage.ts- Local storage management for custom layouts/components- Custom gamepad editor and component implementationsGamepadEditor.tsx- Main drag-and-drop editor interfaceCustomGamepadLayout.tsx- Runtime layout rendererGamepadComponent.tsx- Generic component wrapperJoystickComponent.tsx,ButtonComponent.tsx,DPadComponent.tsxToggleComponent.tsx,SliderComponent.tsx- Input components
/src/hooks- Custom React hooks (useRos.ts,useRos3d.ts, etc.)/src/utils- Utility functions and helpers/ros3d- Core ROS 3D logic and primitive definitions/visualizers- Pure logic for PointCloud, LaserScan, etc.
/src/types- TypeScript type definitionsvitest.config.ts- Unit test configurationplaywright.config.ts- E2E test configuration
๐จ Adding Custom Gamepad Layouts
Use the built-in Custom Gamepad Creator accessible through the "+" button in control panel tabs. No coding required!
- Drag-and-drop interface with pre-built components
- Perfect for most use cases and quick prototyping
- Supports joysticks, buttons, D-pads, toggles, and sliders
- Real-time preview and easy ROS topic configuration
When the in-app system isn't enough for your specific needs, you can implement custom gamepads via code:
- Advanced Components: Create custom component types not available in the drag-and-drop editor
- Complex Logic: Implement sophisticated control algorithms and state management
- Performance Optimization: Fine-tune for high-frequency or specialized operations
- Custom ROS Integration: Support for complex message types, actions, and services
Implementation Paths:
- Hardcoded Layouts: Create traditional gamepad components in
/src/components/gamepads - Extend Custom System: Add new component types to the custom gamepad library
- Comprehensive Guide: See the detailed README in
/src/features/customGamepadfor:- Architecture overview and component system
- Adding new component types to the library
- Extending ROS message support
- Storage format and data structures
