EasyRobot is a cross-platform robotics framework designed to enable algorithm development on desktop/cloud environments and deployment on embedded systems (Raspberry Pi, Nano Pi, ARM microcontrollers). The framework emphasizes:
- Cross-platform compatibility: Intel/AMD, ARM, Xtensa, RP2040, WASM
- Multi-compiler support: Go and TinyGo
- Minimal copying: Zero-copy message passing where possible using typed protobuf messages
- Modular architecture: ROS-like component system with typed communication
- Performance: Optimized for embedded systems with in-place operations
- Pipeline-based processing: Data flows through typed pipelines with steps (sources, processors, sinks)
- Protobuf as communication layer: All inter-component communication uses protobuf for type safety and serialization
- Plugin system: Extensible plugin registry for dynamic component loading
- Backend abstraction: Multiple backends (GoCV, TF, TFLite, native) for algorithm implementations
- Zero-copy where possible: Channels and reference passing minimize memory copies
┌─────────────────────────────────────────────────────────────┐
│ Application Layer │
│ (Vision pipelines, Robot control, Navigation, etc.) │
└─────────────────────────────────────────────────────────────┘
│
┌─────────────────────────────────────────────────────────────┐
│ Domain Packages │
│ pkg/vision pkg/robot pkg/navigation pkg/ai │
└─────────────────────────────────────────────────────────────┘
│
┌─────────────────────────────────────────────────────────────┐
│ Core Framework │
│ Pipeline │ Plugin │ Store │ Transport │ Math │ Logger │
└─────────────────────────────────────────────────────────────┘
│
┌─────────────────────────────────────────────────────────────┐
│ Backend Implementations │
│ GoCV │ TF │ TFLite │ Native (float32) │ Device Drivers │
└─────────────────────────────────────────────────────────────┘
pipeline: Graph-based processing pipeline
- Steps: Source, Processor, Sink, FanIn, FanOut, Join, Sync
- Data flow: Channels with typed Store messages
- Configuration: JSON serializable pipeline definitions
plugin: Dynamic plugin system
- Registry-based plugin loading
- Options-based configuration
- Marshaling support for persistence
store: Typed key-value store
- FQDN-based type system
- Value lifecycle management (Close, Clone)
- Type-safe getters/setters
transport: Communication layer
- NATS backend implementation
- Protobuf message encoding/decoding
- Stream-based transport (video, audio, sensors)
math: Mathematical primitives
- Vector operations (2D, 3D, 4D, generic)
- Matrix operations (2x2, 3x3, 4x4, generic)
- Interpolation (linear, bezier, cosine, spline)
- Filters (PID, AHRS - Madgwick/Mahony)
- Tensor support (dense/sparse)
logger: Logging abstraction
- ZeroLog backend
- Build-tag based optimization (
loglessfor embedded)
kinematics: Forward and inverse kinematics
- Denavit-Hartenberg parameterization
- Planar kinematics (2DOF, 3DOF)
- Wheel kinematics (differential, mechanum)
- Configurable via protobuf
actuator: Actuator control
- Motor control (PWM, encoder)
- Servo control
- Protocol-based configuration
transport: Robot-specific transport
- Packet-based protocol
- Header with magic, ID, CRC
- Type-safe packet routing
reader: Image/video input
- Device capture (camera)
- Video file reading
- Image file reading
- Backend: GoCV
transform: Image transformations
- Color space conversion
- Format conversion
- Stereo processing
extract: Feature extraction
- DNN inference (OpenCV DNN backend)
- Feature detection (ORB, SIFT)
- Backend: GoCV
display: Visualization
- Image display
- Backend: GoCV
writer: Image/video output
- Image file writing
- Video file writing
- Null sink (for testing)
- Pipeline Steps: Use Go channels for zero-copy message passing
- NATS Transport: Distributed communication via NATS with protobuf encoding
- Robot Transport: Packet-based protocol for embedded devices (I2C/SPI/Serial/CAN)
DNDM (Decentralized Named Data Mesh) could replace or complement current transport:
Benefits:
- Intent/Interest pattern matches pipeline source/sink model
- Type-safe routes (
Type@pathformat) - Zero-copy local communication
- Distributed communication via endpoints
- Mesh networking support
Migration Considerations:
- Pipeline
Stepinterface could use DNDM routes instead of channels - NATS transport could be implemented as DNDM endpoint
- Robot transport packets could be wrapped in DNDM messages
Source → [Processor1] → [FanOut] → [Processor2] → [FanIn] → [Sink]
↓ ↓
[Sync] [Join]
Data Type: store.Store - Typed key-value container
Transport: Go channels (local), NATS/DNDM (distributed)
- Store: Generic container with FQDN-typed values
- Protobuf Messages: Generated from
.protofiles - Transport Messages: Wrapped protobuf with headers/metadata
Go (standard):
- Full feature set
- All backends available
- Development and testing
TinyGo:
- Subset of features (no reflection, limited stdlib)
- Embedded-friendly code generation
- Direct hardware access
Intel/AMD (x86_64):
- Full backend support
- Optimized math operations
- Desktop/server deployment
ARM (AArch64, ARMv7):
- Full backend support
- Raspberry Pi, Nano Pi
- Optimized for embedded Linux
Xtensa:
- Limited backend support (native math only)
- ESP32, ESP8266
- No GoCV, minimal dependencies
RP2040:
- Minimal backend support
- Raspberry Pi Pico
- Native math, basic I/O
WASM:
- Subset of features
- Web deployment
- Browser-based visualization
-
Communication Strategy:
- Should DNDM completely replace NATS transport?
- How should pipeline steps communicate across network boundaries?
- Should we support both channel-based (local) and DNDM-based (distributed) communication?
- How to handle hybrid scenarios (some steps local, some remote)?
-
Type System:
- Should we maintain FQDN-based type system or migrate to protobuf message types?
- How to handle type conversion between different backends (GoCV Mat vs image.Image vs TF tensor)?
- Should type information be available at runtime for dynamic pipelines?
-
Backend Strategy:
- How to handle missing backends on embedded platforms?
- Should we provide fallback implementations?
- How to configure backend selection at compile-time vs runtime?
-
Pipeline Configuration:
- Should pipeline definitions be declarative (JSON/YAML)?
- How to handle dynamic pipeline modification?
- Should we support pipeline versioning?
-
Memory Management:
- Should we use memory pools for frequently allocated types (Store, matrices)?
- How to handle zero-copy constraints with serialization?
- Should we support explicit memory management for embedded systems?
-
Concurrency:
- How to handle goroutine lifecycle in pipeline steps?
- Should we support worker pools for parallel processing?
- How to prevent goroutine leaks in long-running pipelines?
-
Real-time Constraints:
- How to handle real-time requirements on embedded systems?
- Should we support priority-based scheduling?
- How to handle deadline misses?
-
DNDM Integration:
- Should DNDM routes map directly to pipeline step names?
- How to handle pipeline step discovery across network?
- Should pipeline connections be established automatically via DNDM?
-
Hardware Abstraction:
- How to abstract hardware-specific features (GPIO, I2C, SPI)?
- Should we provide HAL (Hardware Abstraction Layer)?
- How to handle different hardware capabilities across platforms?
-
Deployment:
- How to package and deploy pipelines to embedded devices?
- Should we support over-the-air updates?
- How to handle configuration management?
-
Type Safety:
- Runtime type checking in Store (could be compile-time with generics)
- No compile-time verification of pipeline connections
- Type conversion errors only caught at runtime
-
Error Handling:
- Error propagation through pipeline could be improved
- No structured error types
- Limited error recovery mechanisms
-
Testing:
- Missing comprehensive test coverage
- Limited integration tests
- No performance benchmarks
- Vector module requires explicit coverage for slice-backed in-place behaviour vs fixed-size value semantics (see
pkg/core/math/vec/TEST_PLAN.md) - Matrix module requires the same in-place vs value-semantics coverage across all fixed-size variants (see
pkg/core/math/mat/TEST_PLAN.md)
-
Documentation:
- Incomplete API documentation
- Missing usage examples
- No architecture diagrams
-
Memory:
- No memory pooling for frequent allocations
- Potential memory leaks in long-running pipelines
- No memory usage monitoring
- Generics: Use Go generics (1.18+) for type-safe Store operations
- Context Propagation: Better context handling throughout pipeline
- Metrics: Add observability (metrics, tracing)
- Backpressure: Implement proper backpressure handling
- Serialization: Optimize protobuf encoding/decoding
- Code Generation: Better code generation for platform-specific optimizations
- Testing: Comprehensive test suite with embedded device simulation
- Examples: Complete examples for common use cases
- Metrics and observability
- Distributed tracing
- Configuration management
- Over-the-air updates
- Hardware abstraction layer
- Simulator integration
- ROS bridge/compatibility
- Web-based visualization
- Machine learning training pipelines
- Zero-copy serialization across network boundaries
- Real-time scheduling for embedded systems
- Distributed pipeline execution
- Hardware acceleration integration
- WASM performance optimization