mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-16 01:21:20 -04:00
documentation
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
# access control modes:
|
||||
- open
|
||||
- open to the public
|
||||
- users are randomly assigned a rover to drive, with priority on the rover with the least amount of drivers
|
||||
- if there are multiple people on one rover, those people will all be controlling that rover at the same time
|
||||
- turns
|
||||
- open to the public
|
||||
- users are randomly assigned to a rover same as open mode
|
||||
- if there are multiple people on one rover, they will each have one minute at a time to drive.
|
||||
- the turn queue loops
|
||||
- the rover will stop moving and stop all aux. motors if the turn switches to a different person
|
||||
- admin
|
||||
- admin authentication is required to access the driver page at all
|
||||
- lockdown
|
||||
- ONLY lockdown admins can access the driver page
|
||||
- the future spectator page is DISABLED (not even a way to log into it)
|
||||
|
||||
# roles in the access control system:
|
||||
- user
|
||||
- default, for normal people who visit the site
|
||||
- admin
|
||||
- authentication needed
|
||||
- can drive and view any rover when not on lockdown, no matter who is controlling it
|
||||
- can switch modes (including switching to lockdown mode)
|
||||
- lockdown admin
|
||||
- authentication needed
|
||||
- only works if said admin has lockdown: enabled in config
|
||||
- can ALWAYS access and control EVERYTHING that there is to do on the site
|
||||
|
||||
# other things to keep in mind:
|
||||
- in the future, there will be a Discord bot for community alerts and a few admin controls
|
||||
- wherever the admin list is configured, there has to be a spot for their discord ID
|
||||
- admin's discord IDs are linked to their admin name server-side
|
||||
@@ -0,0 +1,27 @@
|
||||
# general idea
|
||||
- uses the rover's reported battery full, warn, and urgent values
|
||||
- will apply to all rovers individually
|
||||
- uses the rover locking system
|
||||
- completely server side
|
||||
- always use the battery warn value as 0% battery and the full value as 100%
|
||||
|
||||
## first: the server-side server-wide event bus
|
||||
- global server event bus
|
||||
- used for realtime alerts between modules
|
||||
- includes a way to tell where the event is coming from
|
||||
|
||||
## what will the battery manager do?
|
||||
- watch each rover's battery charge number (reported in sensors)
|
||||
- if the number reaches warn, fire an event on the event bus
|
||||
- the UI will show a warning to users, independently based on sensor data
|
||||
- once the rover is docked and charging, lock it.
|
||||
- when the battery is fully charged, unlock it.
|
||||
|
||||
## while we're at it...
|
||||
- add a lock reason to the rover locking system
|
||||
- add the following to the rover roster in the UI session state:
|
||||
- battery full #
|
||||
- battery warn #
|
||||
- battery urgent #
|
||||
- in the rover roster UI component, add a display for battery percentage and lock reason.
|
||||
- make the rover's background red when locked
|
||||
@@ -0,0 +1,9 @@
|
||||
# general idea
|
||||
- IR led on the front of each roomba
|
||||
- connected to a pin on the pi
|
||||
- made to be very directional
|
||||
- each roomba has a different IR code
|
||||
- use the omni reciever to get a shot
|
||||
- keep score per user
|
||||
- use the go alert system
|
||||
- alert discord with a live score count
|
||||
@@ -0,0 +1,36 @@
|
||||
# Video flow (SRT ingest, WHEP playback)
|
||||
|
||||
1. **Raspberry Pi Zero 2 W**
|
||||
- `pi/bin/video-publisher.sh` captures the CSI camera with `rpicam-vid`/`libcamera-vid` using the onboard H.264 encoder (`--inline --profile baseline --bitrate …`).
|
||||
- The Annex-B stream is piped into the stock FFmpeg package and pushed to the control server over SRT as MPEG‑TS: `ffmpeg -f h264 -i - -c copy -f mpegts "srt://<server>:9000?streamid=#!::r=rover-alpha,m=publish&latency=20&mode=caller&transtype=live&pkt_size=1316"`.
|
||||
- Configuration lives in `/var/lib/roverd/video.env` (`PUBLISH_URL`, resolution, FPS, bitrate). `roverd` rewrites this file whenever the rover config changes, so onboarding a new rover is just flashing the SD card, setting its `name`, and plugging it into the trusted LAN—**no auth or per-rover server config is required on the Pi ⇄ server hop.**
|
||||
|
||||
2. **mediaMTX on the server**
|
||||
- Single wildcard path handles every rover:
|
||||
```yaml
|
||||
paths:
|
||||
"~^rover-(?P<id>[a-z0-9_-]+)$":
|
||||
source: publisher
|
||||
sourceOnDemand: no
|
||||
sourceProtocol: srt
|
||||
readBufferCount: 512
|
||||
webrtcEnable: yes
|
||||
webrtcMaxPlayoutDelay: 0
|
||||
alwaysRemuxWhep: no
|
||||
```
|
||||
- Pis publish to `srt://<server>:9000` with the streamid above; mediaMTX auto-creates the path and fans it out over WHEP/WebRTC. If you expose playback under `/video/<id>` externally, let the reverse proxy rewrite that prefix back to `<id>` before forwarding to mediaMTX so the wildcard continues to match every rover.
|
||||
- Only playback is gated: mediaMTX calls the Node server to validate JWTs on `/whep/rover-<id>`, so “locking” a stream is as simple as refusing to mint viewer tokens for that rover. Ingest stays unauthenticated because it lives on a secure LAN.
|
||||
|
||||
3. **Web clients**
|
||||
- Tiny helper (React hook or vanilla class) that:
|
||||
1. Requests a viewer token for rover `<id>`.
|
||||
2. Issues a `POST` to `<mediamtx-host>/<rover-id>/whep` with `Authorization: Basic base64(token:token)` (token issued by the server when the client calls `video:request`).
|
||||
3. Maintains auto-reconnect timers on ICE failure so dashboard widgets can come/go without reloading the page.
|
||||
- Operator dashboard mounts one player tied to the assigned rover. The spectator view instantiates one player per tile, muting + pausing hidden elements to keep CPU usage sane even when every rover is shown simultaneously.
|
||||
|
||||
# Deployment checklist
|
||||
|
||||
- `pi/install_roverd.sh` installs the `video-publisher` helper, drops `/var/lib/roverd/video.env`, and pulls in `libcamera-apps` + `ffmpeg` from apt. No custom FFmpeg, no WHIP builds, no extra config—Pis become plug-and-play.
|
||||
- `roverd` derives `media.publishUrl` automatically from `serverUrl`: `srt://<server>:9000?streamid=#!::r=<name>,m=publish&latency=20&mode=caller&transtype=live&pkt_size=1316`. The media supervisor rewrites `video.env` and manages `video-publisher.service` whenever you hit “Restart Camera” or change `/etc/roverd.yaml`.
|
||||
- The server’s mediaMTX config switches to the wildcard block above, leaves SRT ingest open, and enforces JWTs only on WHEP viewers. Fan-out stays inside mediaMTX so every browser sees the same low-latency stream (≈250–350 ms glass-to-glass).
|
||||
- Adding a rover = flash SD → set `/etc/roverd.yaml` (`name`, `serverUrl`, camera knobs if needed) → boot it. The server auto-discovers the new `rover-<id>` stream with zero manual edits.
|
||||
@@ -0,0 +1,58 @@
|
||||
## multi roomba rover
|
||||
|
||||
a website where people can control multiple irobot create 2 robots in real time 100% responsively
|
||||
with a raspberry pi zero 2 W on each roomba, along with a raspberry pi camera
|
||||
a central nodejs control server will tell the raspberry pis what to do with the roomba
|
||||
|
||||
## the pi side (roomba side)
|
||||
- pi's onboard UART is hooked up to the roomba's serial port
|
||||
- another GPIO pin connected to the roomba's BRC pin
|
||||
- pull it low for one second every minute to keep the roomba awake
|
||||
- streams the rpi camera over webRTC with mediamtx
|
||||
- streams roomba sensor group 100 to the server
|
||||
- sensor streaming is required and important, but is allowed to falter sometimes
|
||||
- listens for roomba commands from the server
|
||||
- commands NEED to happen
|
||||
- roomba control program needs to be simple, lightweight, and 100% responsive
|
||||
|
||||
## pi -> server communication
|
||||
- stateless
|
||||
- streaming based
|
||||
- on connection, the pi will send the following info:
|
||||
- rover's name
|
||||
- motor enable / disable
|
||||
- vacuum
|
||||
- main brush
|
||||
- side brush
|
||||
- battery full number
|
||||
- battery warning number
|
||||
- battery urgent number
|
||||
|
||||
## nodejs server
|
||||
- KISS
|
||||
- decode the sensor data from each roomba
|
||||
- can support multiple roombas connected from the ground up
|
||||
- keep it simple, worry about getting the pi comms right.
|
||||
- but the server DOES have to exist for testing
|
||||
- IS the web server, hosts an entire static folder for the web UI
|
||||
|
||||
## server -> web UI communication
|
||||
- socket.io
|
||||
- don't do anything fancy with the socket.io setup
|
||||
- it works fine out of the box, we will optimize it later
|
||||
|
||||
## the web UI
|
||||
- KISS
|
||||
- plain old html. no styling even. just bare minimum for testing
|
||||
- what it needs to do:
|
||||
- allow user to select the roomba from a list
|
||||
- make the selected roomba drive with WASD
|
||||
- have buttons to set the OI mode, and tell the roomba to dock
|
||||
- show a plain list of the sensor data from the selected roomba
|
||||
|
||||
### general javascript programming guidelines (applies to the web UI too)
|
||||
- everything ES6
|
||||
- one entrypoint file in the web UI
|
||||
- everything modular
|
||||
- everything easy to read, understand, and work on
|
||||
- comment where you think is best to describe whats going on
|
||||
@@ -0,0 +1,13 @@
|
||||
# general idea
|
||||
- servo connected to pin 19 on the pi
|
||||
- it will allow the camera to look up and down
|
||||
- use go-rpio
|
||||
- it has a hardware PWM implementation
|
||||
- mechanical design will have limits
|
||||
- set the limits in roverd config
|
||||
- control the servo from the web browser
|
||||
- expose both a slider and buttons for "nudging" it up and down
|
||||
|
||||
## verification of functionality before full implementation
|
||||
- make sure that the go program can properly use the GPIO correctly before full implementation
|
||||
- modify the roverd installer to add the needed stuff to enable PWM access
|
||||
@@ -0,0 +1,19 @@
|
||||
## raspberry pi
|
||||
- need to throttle sensor sending, maybe only send one in every 5 packets.
|
||||
|
||||
## 3d models for camera:
|
||||
- https://www.thingiverse.com/thing:2873677
|
||||
- https://www.printables.com/model/356894-raspberry-camera-module-with-automatic-ir-cut-swit
|
||||
- https://www.thingiverse.com/thing:4514531
|
||||
|
||||
## spectator page
|
||||
- video does not load in spectator page in admin mode
|
||||
|
||||
## todo
|
||||
1. battery manager
|
||||
2. room cameras
|
||||
3. nicknames
|
||||
4. discord bot
|
||||
5. turns mode display
|
||||
6. chat
|
||||
7. redo spectator view (last)
|
||||
@@ -0,0 +1,69 @@
|
||||
# general idea
|
||||
- a modular control system
|
||||
- every piece of the UI that uses rover controls will go through this, including onscreen click buttons
|
||||
- allows for dynamic control labels based on saved settings
|
||||
- allow a place to assign OI command macros
|
||||
- like the one that the drive button uses now
|
||||
- allows realtime responsive control of the rover that you are driving
|
||||
|
||||
## some sort of system for the site to save settings per browser
|
||||
- needs to be extensible
|
||||
- future things will use it
|
||||
- expose functions like saveSettings and loadSettings
|
||||
- other parts of the UI will need to save and load settings using this function
|
||||
- use cookies
|
||||
|
||||
## keyboard controls:
|
||||
- remappable by new component in settings tab
|
||||
- key mappings will save
|
||||
- controls for the keyboard
|
||||
- driving
|
||||
- WASD blended for tank steering
|
||||
- hold backslash to move faster
|
||||
- hold right shift to move slower
|
||||
- aux motors
|
||||
- main brush
|
||||
- hold O to move it forward at speed 127
|
||||
- hold L to move it backward at speed -127
|
||||
- side brush
|
||||
- hold P to move it forward at speed 127
|
||||
- hold ; to move it backward at speed -70
|
||||
- vacuum motor
|
||||
- hold [ to move it at speed 127
|
||||
- hold ' to move it at speed 50
|
||||
- ALL AUX MOTORS
|
||||
- hold . to move at full speed forward (127)
|
||||
- camera movement
|
||||
- hold I to look up
|
||||
- hold K to look down
|
||||
- dock and drive hotkeys
|
||||
- G for drive (use same 3 part macro as the drive button)
|
||||
- H for dock (seek dock command)
|
||||
|
||||
## Mobile controls
|
||||
- 2 different layouts, already implemented just needs improved.
|
||||
### mobile landscape
|
||||
- a video game style layout
|
||||
- on the left, buttons that you hold to operate the aux motors
|
||||
- in the middle, is the rover video component.
|
||||
- on the right, an area for a floating joystick and above is a unified control to see and change the rover's mode (drive or dock)
|
||||
### mobile portrait
|
||||
- designed to be driven vertically with 2 hands
|
||||
- mostly fine already
|
||||
- rover video at the top
|
||||
- then below it, is a section with the aux motor buttons on the left, and the floating joystick are on the right.
|
||||
|
||||
|
||||
## Gamepad controls:
|
||||
- use some sort of react thing that makes it easy to use the web gamepad stuff
|
||||
- left joystick for movement, right joystick for moving camera up / down
|
||||
- both fully analog
|
||||
- right trigger for the main brush motor
|
||||
- fully analog
|
||||
- press right bumper to switch it to reverse
|
||||
- left trigger for the side brush motor
|
||||
- fully analog
|
||||
- press left bumper to switch it to reverse
|
||||
- hold the right face button to run the vacuum motor
|
||||
- hold the lower face button to run all aux motors forward
|
||||
- left and right on the Dpad switch between drive and dock modes
|
||||
@@ -0,0 +1,51 @@
|
||||
# server code structure:
|
||||
The server's internal structure will be modular, and by modular i mean completely modular,
|
||||
the modules will import what they need from other modules, and export what other modules will need from them.
|
||||
the entrypoint file will contain nothing but a long list of `require('')`s for all of the modules in the proper order
|
||||
|
||||
for example, A service which automatically assigns a newly connected user to a roomba that isn't in use.
|
||||
this service would import the roomba list from whatever other service contains it, and import the global socket.io server instance. It will add its own io.on('connection') to the socket.io instance, which contains the logic for assigning users to roombas.
|
||||
|
||||
- modular code structure
|
||||
- one folder for each of these categories
|
||||
- globals
|
||||
- GLOBALS ARE: "static" parts of the server that don't contain any interactive logic.
|
||||
- where the express, websocket, and socket.io instances will be
|
||||
- other global things
|
||||
- services
|
||||
- SERVICES ARE: parts of the program that are part of the interaction pipeline.
|
||||
- contains things like the roomba manager
|
||||
- will also in the future contain other things like a discord bot, home assistant integration, etc
|
||||
- anything with a large amount of controlling logic should be in here
|
||||
- helpers
|
||||
- HELPERS ARE: parts of the program that other modules only pull helper funcions or classes from.
|
||||
- if a function or class is dedicated to a service, it should NOT be in a helper.
|
||||
- contains passive helpers
|
||||
- things like the logger system
|
||||
- no "service" logic in here, only things that are passively pulled out and used inside other modules
|
||||
- one entrypoint file that contains NOTHING but `require('')`s.
|
||||
|
||||
|
||||
|
||||
# server <-> web client logistics
|
||||
|
||||
I want each connected roomba to have a list of drivers. if a socket is not in this list, they are not allowed to drive the roomba. I will be adding admins, authentication, a turns system, and automatic roomba assignment later so it is important that we start with this system in place.
|
||||
a roomba's list of drivers will be completely managed by the server, users should not be able to change driver lists, even in a hacky way.
|
||||
|
||||
Each user will also have to see sensor data from the roomba that they are controlling. I want it to be done in this way:
|
||||
- for each connected roomba, there is a socket.io room where all of the sensor data is streamed out to clients
|
||||
- the client will be added to the room, where they can see all of the active roomba's sensor data
|
||||
- ALSO for future use, it needs to work properly if a socket is subscribed to all rooms, in the future there will be a spectator page which can view all of the roombas at once.
|
||||
|
||||
I want there to be a ground up system where I can set the entire service to four different modes:
|
||||
- open (anyone can drive, roombas are assigned randomly. if they are all full, two people will be controlling the same roomba)
|
||||
- turns (anyone can drive, roombas are assigned randomly. if they are all full, each person gets one minute on their selected roomba)
|
||||
- admin (only authenticated admins can log in, anyone can still view but no one is allowed to drive but admins)
|
||||
- lockdown (only "lockdown" admins can view or drive. no one else can view, not even spectators).
|
||||
only admins can change modes.
|
||||
|
||||
do NOT implement any authentication stuff yet, just add a stub service with places set up to put the auth. logic
|
||||
|
||||
# web client code structure:
|
||||
- the same as the server's code structure
|
||||
- all ES6
|
||||
@@ -0,0 +1,67 @@
|
||||
# general idea:
|
||||
- very compact UI
|
||||
- utilitarian
|
||||
- function before pretty
|
||||
- tiny text, too.
|
||||
- no large margins or padding. very little wasted space
|
||||
- up to 1 tailwind unit unless otherwise needed
|
||||
- black background, gray cards, white or gray text
|
||||
- tailwind
|
||||
- no title or bar at the top, vertical screen space is precious on all layouts
|
||||
- alerts should be moved to a tiny toast popup that will show at the top center of the screen
|
||||
|
||||
# three different layouts for the driver page
|
||||
- desktop
|
||||
- rover video central, no title or anything above it
|
||||
- overlayed on rover video (HUD like in a video game)
|
||||
- build the HUD into the video tile
|
||||
- because everywhere the video is, the HUD should be too
|
||||
- shows a dot that blinks on each sensor frame
|
||||
- shows wheel drops and bumpers
|
||||
- shows a big "loud" warning overlay during an overcurrent
|
||||
- simple, easy to understand battery bar UNDERNEATH the video:
|
||||
- takes in battery full, warn, and urgent values
|
||||
- treat full as 100% and warn as 0%
|
||||
- make the bar flash red when its 0% or lower
|
||||
- on left side of rover video:
|
||||
- sensor data, visualized.
|
||||
- battery charge out of capacity (1763/2068)
|
||||
- charging status
|
||||
- OI mode
|
||||
- battery voltage (in volts not mv)
|
||||
- battery current
|
||||
- a teeny show of the raw data (because we get it on the client and it looks cool)
|
||||
- on right side of rover video
|
||||
- a simple, easy control panel with the following actions:
|
||||
- a button that runs the start OI, dock, then full commands (in that order)
|
||||
- also contains a little status of whether or not the rover is in "driving mode" (OI in full mode)
|
||||
- a button that tells the rover to seek dock
|
||||
- explains that you should be straight in front of, and about a foot from the dock for a successful attempt
|
||||
- contains two status indicators:
|
||||
- docked / not docked (homebase true)
|
||||
- charging / not charging (when chargingstate isn't "not charging" the rover is charging)
|
||||
- below the upper control and video row
|
||||
- center:
|
||||
- a place for the room camera (not implemented yet)
|
||||
- left:
|
||||
- admin login and controls
|
||||
- right:
|
||||
- logs
|
||||
- mobile in portrait mode
|
||||
- rover video at the top, with HUD
|
||||
- just below:
|
||||
- joystick with buttons for aux. motor controls
|
||||
- have a button to run all aux motors forward at max speed
|
||||
- also have buttons to run motors forward / backward individually
|
||||
- probably use some premade react joystick
|
||||
- scroll down more to see:
|
||||
- the same simple mode control buttons from the desktop layout
|
||||
- also needs to have the admin login and controls
|
||||
- needs to have all the functionality as the desktop page
|
||||
- mobile in landscape mode
|
||||
- made for videogame-like control of the rover
|
||||
- control buttons and aux motors on the left
|
||||
- rover video in the middle
|
||||
- joystick on the right
|
||||
- again, scroll down to see more
|
||||
- also has to do everything
|
||||
Reference in New Issue
Block a user