run() or run_threaded() method and can be added to the vehicle loop.
What is a Part?
A part is a modular component that:- Takes inputs from Memory
- Performs some processing or I/O
- Returns outputs to Memory
- Runs on each iteration of the vehicle loop
Part Interface
The minimal part interface is simply arun() method:
Full Interface
A complete part may implement:Adding Parts to Vehicle
Parts are registered with the Vehicle usingadd():
Example
Input/Output Flow
The Vehicle automatically manages data flow:- Get inputs: Vehicle reads input values from Memory
- Call part: Passes inputs as arguments to
run()orrun_threaded() - Store outputs: Vehicle writes return values to Memory
Single Output
Multiple Outputs
No Output
The number of return values must match the number of outputs specified. For multiple outputs, return a tuple:
return output1, output2Synchronous vs Threaded Parts
Synchronous Parts (Default)
When to use: Fast operations (< 10ms)throttle_filter.py:2-25.
Threaded Parts
When to use: Slow I/O operations (cameras, network, sensors)camera.py:23-82.
How it works:
update()runs in a background thread, continuously callingrun()- Main vehicle loop calls
run_threaded()to get latest cached result - No blocking of the main drive loop
Threaded parts should store results in instance variables (like
self.frame). The main loop just reads the cached value, preventing slow I/O from blocking the drive loop.Real-World Part Examples
Example 1: Transform Part
Simple functional wrapper fromtransform.py:5-19:
Example 2: DriveMode Part
Logic part frombasic.py:28-42:
Example 3: PID Controller
Stateful processing part fromtransform.py:53-115:
Example 4: TriggeredCallback
Event-driven part fromtransform.py:21-31:
Example 5: Conditional Logic Part
Fromsimulator.py:122-128:
Run Conditions
Parts can execute conditionally:vehicle.py:194-196):
complete.py:415:
Use Cases
- Mode switching: User vs autopilot
- Conditional recording: Only record when button pressed
- Button handlers: Execute when button pressed
- Feature toggles: Enable/disable features
Memory Channel Naming Conventions
Follow these patterns for clarity:- Sensors:
cam/image_array,imu/acl_x,lidar/dist_array - User input:
user/angle,user/throttle,user/mode - Autopilot:
pilot/angle,pilot/throttle,pilot/loc - Actuators:
steering,throttle,brake - Recording:
recording,tub/num_records - Conditions:
run_pilot,run_user - Web UI:
web/buttons,web/w1,web/w2
Creating Custom Parts
Simple Processing Part
Sensor Part with Threading
Actuator Part
Filter Part
Best Practices
- Keep parts simple: Each part should do one thing well
- Make I/O threaded: Cameras, network, sensors should run in background
- Store state in instance variables: For stateful parts like filters or accumulators
- Implement shutdown: Clean up resources (close files, stop motors, etc.)
- Handle None gracefully: Inputs may be None on first iteration
- Use meaningful names: Clear input/output channel names
- Document your parts: Add docstrings explaining purpose and usage
- Test independently: Parts should be testable without the vehicle loop
Part Testing
Test parts independently before adding to vehicle:Common Patterns
Button Handler
Data Pipeline
Conditional Branching
Next Steps
- Learn about the Vehicle Loop and execution model
- Understand the Memory system
- Explore Templates to see parts in action
- Read the Architecture overview
