Plugin Development¶
AVLite supports three types of plugins:
- Built-in plugins (avlite/plugins/): Maintained by the core team
- Community plugins: Public registry via pull request to avlite-community-plugins
- Member plugins: AV-Lab private registry (avlite-private-plugins); browse/install via the Members tab after GitHub sign-in
This guide covers creating community plugins. Classes inheriting from base strategies automatically register and appear in the UI.
What you can extend¶
| Layer | Base classes | UI / config |
|---|---|---|
| Perception | PerceptionStrategy or DetectionStrategy / TrackingStrategy / PredictionStrategy via PerceptionPipeline |
Main Perception dropdown; pipeline sub-dropdowns (Detect / Track / Predict) appear only when PerceptionPipeline is selected |
| Localization | LocalizationStrategy |
Separate Localization dropdown (optional; independent of perception) |
| Mapping | MappingStrategy |
Extendable via plugin; registry-based like other strategies |
| Planning | GlobalPlannerStrategy, LocalPlanningStrategy |
Global / local planner dropdowns |
| Control | ControlStrategy |
Controller dropdown |
| Execution | WorldBridge |
Bridge dropdown (BasicSim, Carla, Gazebo, ROS2, or custom) |
Perception: monolithic vs pipeline¶
Perception is the most flexible layer — you can replace the whole stack in one class, or plug in individual stages.
flowchart TB
subgraph mono ["Monolithic PerceptionStrategy"]
M1["MyPerception.perceive()"]
M1 --> M2["detect + track + predict in one class"]
end
subgraph pipe ["PerceptionPipeline composes sub-strategies"]
P1["DetectionStrategy.detect()"]
P2["TrackingStrategy.track()"]
P3["PredictionStrategy.predict()"]
P1 --> P2 --> P3
end
Exec["Execution selects perception by class name"]
Exec --> mono
Exec --> pipe
Monolithic (PerceptionStrategy):
- Implement all stages in one
perceive()method. - Select your class name in the main Perception dropdown, or set
c40_perceptioninc40_execution.yaml/perception_typein the visualization profile. - Example built-in:
MultiObjectPredictor(p10_perception_MO_prediction).
Pipelined (PerceptionPipeline + sub-strategies):
- Set perception to
PerceptionPipelinein the main dropdown. - The GUI shows Detect, Track, and Predict sub-dropdowns (only visible in pipeline mode).
- Configure sub-strategies in
configs/c10_perception.yaml:
c12_detection_strategy: MyDetector # empty → ground truth from bridge
c12_tracking_strategy: MyTracker # empty → ground truth from bridge
c12_prediction_strategy: MyPredictor # empty → prediction stage skipped
- Each sub-strategy has its own registry; plugin classes auto-register like monolithic strategies.
- Empty name: detection/tracking use ground truth from the world bridge when available; prediction is skipped if unset.
- Non-empty unknown name: factory raises on reload (shown in the visualizer as "Reload failed").
- Mix core and plugin sub-strategies freely (e.g. core
FastBEVLidarDetection+ pluginMyPredictor).
Localization is separate from PerceptionPipeline: optional LocalizationStrategy in its own dropdown; updates PerceptionModel.ego_vehicle in-place.
Planning, control, and world bridge¶
- Planning — subclass
GlobalPlannerStrategy(plan()) orLocalPlanningStrategy(replan()); selected via global/local planner dropdowns; configured inc40_execution.yaml(c40_global_planner,c40_local_planner). - Control — subclass
ControlStrategy(control()); selected via controller dropdown (c40_controller). - World bridge — subclass
WorldBridge; implement sensor getters andcontrol_ego_state(); selected via Bridge dropdown (c40_bridge). See built-inp40_bridge_*plugins for reference.
Community Plugin Structure¶
Create your plugin anywhere on your system:
/path/to/my_plugin/
├── __init__.py # Export classes
├── settings.py # Optional: PluginSettings if you have tunable params
├── my_strategy.py # Your implementation
├── README.md # Optional: shown in the Plugins browser
└── requirements.txt # Optional: extra pip dependencies
Tunable parameters are saved outside the plugin tree in ~/.config/avlite/plugin_<plugin_name>.yaml (see section 1). Do not ship a config/ folder or plugin-local YAML profiles in your repository.
Do not commit a .venv inside your plugin directory — AVLite scans all .py files under the plugin path and skips common vendor folders (.venv, site-packages, etc.), but keeping the venv outside the plugin tree is cleaner.
1. Settings File (Optional)¶
If your plugin has tunable parameters, add settings.py with a PluginSettings class. AVLite creates settings widgets automatically and saves profiles to ~/.config/avlite/plugin_<plugin_name>.yaml (or under AVLITE_CONFIG_DIR if set). The filename uses the registry key / c62_community_plugins entry name — you do not need exclude, filepath, or a config/ folder in your plugin package; AVLite derives the settings path when the plugin is registered and loaded.
# settings.py
class PluginSettings:
# Your parameters (appear in UI automatically)
my_param: float = 1.0
Optionally add a PluginSettingsSchema (Pydantic) with Field(description=...) for tooltips in the settings window, same as built-in plugins.
If ~/.config/avlite/plugin_<plugin_name>.yaml does not exist yet, AVLite may still read a legacy file at <install>/config/<plugin_name>.yaml from older setups; new saves always go to the user config directory.
Built-in plugins under avlite/plugins/ are different: they set filepath = "configs/plugin_*.yaml" explicitly so shipped defaults live in the repository configs/ directory and fall back from the user config dir on load.
2. Example: Custom Perception (Monolithic)¶
from avlite.c10_perception.c12_perception_strategy import PerceptionStrategy
from avlite.c50_common.c51_capabilities import WorldCapability, StackCapability
from .settings import PluginSettings
class MyPerception(PerceptionStrategy):
def __init__(self, perception_model, setting=None):
super().__init__(perception_model, setting)
@property
def world_requirements(self) -> set[WorldCapability]:
return {WorldCapability.CAMERA_RGB, WorldCapability.LIDAR_3D}
@property
def stack_capabilities(self) -> set[StackCapability]:
return {StackCapability.DETECTION, StackCapability.TRACKING,
StackCapability.PREDICTION}
def perceive(self, rgb_img=None, depth_img=None, lidar_data=None,
perception_model=None):
# Fuse camera and LiDAR to detect, track, and predict agents
# Update self.perception_model.agents in-place, then return it
return self.perception_model
3. Example: Detection, Tracking, or Prediction Sub-Strategy¶
Use DetectionStrategy, TrackingStrategy, or PredictionStrategy when you only need
to implement one stage of the pipeline. These plug into PerceptionPipeline and are
selected by name when Perception is set to PerceptionPipeline.
from avlite.c10_perception.c12_perception_strategy import DetectionStrategy
from avlite.c50_common.c51_capabilities import WorldCapability
from avlite.c10_perception.c11_perception_model import PerceptionModel
class MyDetector(DetectionStrategy):
@property
def world_requirements(self) -> set[WorldCapability]:
return {WorldCapability.CAMERA_RGB}
def detect(self, perception_model: PerceptionModel,
rgb_img=None, depth_img=None, lidar_data=None) -> PerceptionModel:
# Your detection logic here
return perception_model
from avlite.c10_perception.c12_perception_strategy import TrackingStrategy
from avlite.c50_common.c51_capabilities import WorldCapability
from avlite.c10_perception.c11_perception_model import PerceptionModel
class MyTracker(TrackingStrategy):
@property
def world_requirements(self) -> set[WorldCapability]:
return set()
def track(self, perception_model: PerceptionModel) -> PerceptionModel:
# Your tracking logic here
return perception_model
from avlite.c10_perception.c12_perception_strategy import PredictionStrategy
from avlite.c50_common.c51_capabilities import WorldCapability
from avlite.c10_perception.c11_perception_model import PerceptionModel
class MyPredictor(PredictionStrategy):
@property
def world_requirements(self) -> set[WorldCapability]:
return set()
def predict(self, perception_model: PerceptionModel) -> PerceptionModel | None:
# Your prediction logic here
return perception_model
Configure pipeline sub-strategies in configs/c10_perception.yaml:
c12_detection_strategy: MyDetector
c12_tracking_strategy: MyTracker
c12_prediction_strategy: MyPredictor
4. Example: Custom Localization¶
Localization strategies estimate the ego vehicle’s pose and update
self.perception_model.ego_vehicle in-place (no return value).
from avlite.c10_perception.c13_localization_strategy import LocalizationStrategy
from avlite.c50_common.c51_capabilities import WorldCapability, StackCapability
class MyLocalization(LocalizationStrategy):
def __init__(self, perception_model, setting=None):
super().__init__(perception_model, setting)
@property
def world_requirements(self) -> set[WorldCapability]:
return {WorldCapability.LIDAR_3D}
@property
def stack_capabilities(self) -> set[StackCapability]:
return {StackCapability.LOCALIZATION}
def localize(self, imu=None, lidar=None, rgb_img=None) -> None:
# Estimate the ego pose from sensor data and update in-place
if lidar is not None:
# ... your scan-matching / localization logic ...
self.perception_model.ego_vehicle.x = estimated_x
self.perception_model.ego_vehicle.y = estimated_y
self.perception_model.ego_vehicle.theta = estimated_theta
def reset(self):
pass
5. Example: Custom Planner¶
from avlite.c20_planning.c23_local_planning_strategy import LocalPlanningStrategy
class MyLocalPlanner(LocalPlanningStrategy):
def replan(self, perception_model, global_trajectory=None):
# Your local planning logic; return a Trajectory or None
return self.local_trajectory
6. Example: Custom Controller¶
from avlite.c20_planning.c21_planning_model import GlobalPlan, LocalPlan
from avlite.c30_control.c32_control_strategy import ControlStrategy
from avlite.c30_control.c31_control_model import ControlCommand, ControlCommandBase
class MyController(ControlStrategy):
def control(self, ego, plan: GlobalPlan | LocalPlan | None = None, control_dt=None) -> ControlCommandBase:
if plan is not None:
self.set_plan(plan)
return ControlCommand(steer=0.0, acceleration=1.0)
def reset(self):
pass
Use set_trajectory_tracker(tj) when you already have a built TrajectoryTracker; use set_plan(plan) or the plan argument on control() when you hold a GlobalPlan or LocalPlan.
7. Multi-robot agents and control¶
AVLite separates what an agent is (platform metadata) from how it is actuated (control command payload). Phase 1 adds the structure; the executer still drives ego via control_ego_state only. Multi-agent actuation and physics sub-stepping are reserved for later.
Agent identity¶
| ID | Role |
|---|---|
EGO_AGENT_ID = 0 |
Ego vehicle (EgoState in perception_model.ego_vehicle) |
1, 2, 3, … |
NPCs in perception_model.agent_vehicles (assigned by add_agent_vehicle) |
from avlite.c10_perception.c11_perception_model import AgentState, AgentType, EGO_AGENT_ID
npc = AgentState(x=10.0, y=0.0, agent_type=AgentType.DIFF_DRIVE)
agent_id = perception_model.add_agent_vehicle(npc) # returns 1, 2, ...
IDs are stable integers — not Enum.auto() values and not random — so bridges, logs, and tracking stay debuggable.
Two layers (do not conflate)¶
flowchart LR
AgentType["AgentType on AgentState\nplatform metadata"]
CmdClass["ControlCommandBase subclass\nactuation payload"]
Map["control_type_for_agent()\nc38_control_mapping.py"]
Bridge["WorldBridge.control_type(agent)"]
AgentType --> Map --> CmdClass
Bridge --> Map
AgentType— platform category onAgentState(Ackermann car, diff-drive, aerial, pedestrian, …).- Control command classes — actuation payload in
c31_control_model.py; default mapping inc38_control_mapping.py.
Default control mapping¶
AgentType |
Command class | Fields |
|---|---|---|
ACKERMANN |
AckermannControlCommand |
steer, acceleration |
DIFF_DRIVE, CYCLIST |
DiffDriveControlCommand |
linear, angular |
AERIAL, SURFACE_VESSEL, UNDERWATER, PEDESTRIAN, DYNAMIC_OBJECT |
BodyVelocityControlCommand |
vx, vy, vz, yaw_rate |
Set agent_type when spawning non-car NPCs. Do not infer platform type from agent_id — use agent.agent_type.
Backward compatibility¶
ControlCommandandControlComandremain aliases forAckermannControlCommandonly.- Existing car stack code needs no changes; polymorphic APIs use
ControlCommandBase. - Use
isinstance(cmd, ControlCommandBase)for any command type;isinstance(cmd, ControlCommand)matches Ackermann only.
WorldBridge API (phase 1 vs future)¶
| Method | Phase 1 today | Future |
|---|---|---|
control_ego_state(cmd) |
Required; all bridges implement this | Unchanged |
control_type(agent) |
Default: control_type_for_agent(agent) |
Override only for bridge-specific exceptions |
control_agent(id, cmd) |
Default: ego delegates to control_ego_state; NPC raises NotImplementedError |
Override + declare WorldCapability.AGENT_CONTROL |
teleport_agent(id, x, y, theta) |
Default: ego delegates to teleport_ego; NPC raises NotImplementedError |
Override for sim teleport of any agent |
get_*(agent_id=EGO_AGENT_ID) |
Default: ego returns data or None; NPC raises NotImplementedError |
Per-agent sensors in Carla / ROS bridges |
get_sensor_frame(agent_id=...) |
Ego: calls legacy get_*() with no kwargs (BasicSim-compatible) |
Non-ego: passes agent_id to each getter |
step(dt) |
Default no-op; executer does not call it yet | Physics tick with held command; executer sub-stepping |
control_type(agent) lives on WorldBridge only — not on ControlStrategy. The bridge knows what actuation format the sim or robot accepts; the controller expresses what it computes via the return type of control().
Multi-agent sensors: override getters with an agent_id parameter when your bridge serves more than ego. Ego-only bridges (e.g. BasicSim) need no update — get_sensor_frame() uses the legacy no-kwargs call path for ego.
State model — today vs future¶
Today: AgentState uses pose (x, y, z, theta) plus scalar velocity (speed along heading). This matches the car-centric stack (planning, collision checking, BasicSim, visualization).
Aerial / holonomic agents: BodyVelocityControlCommand is defined, but base AgentState does not yet carry vx, vy, or vz. For 2D / bird's-eye use cases, heading plus scalar speed is an acceptable lite projection. Full drone or multirotor simulation needs richer state later.
Future pattern: subclass when kinematics diverge — for example DroneAgentState(AgentState) with body or world velocity fields and custom predict() / integration. Same idea as EgoState(AgentState). Lists typed as list[AgentState] accept subclasses. Keep agent_type for dispatch; use the subclass for extra fields and integration logic.
Plugin author checklist¶
- Set
agent_typeat spawn for non-car NPCs. - Return the command type your controller produces; built-in controllers still return Ackermann today.
- Bridge: implement only what you need now (
control_ego_state); opt intocontrol_agentandAGENT_CONTROLwhen the sim supports NPC actuation. - Do not branch on
agent_idheuristics for platform type — useagent.agent_type. - Converters (Ackermann → diff-drive, etc.) are not in core yet; keep them in your plugin until a shared module (e.g.
c38_control_converters.py) lands.
Prediction models on PerceptionModel¶
Forecast payloads live on a single typed object: perception_model.prediction. Per-agent types store data in dict[int, …] keyed by agent_id (not list index). The lump-sum occupancy type is AggregatedOccupancyFlow (one grid sequence for the whole scene).
from avlite.c10_perception.c11_perception_model import PerceptionModel, SingleTrajectory
pm.prediction = SingleTrajectory(
predict_delta_t=0.1,
trajectories={agent.agent_id: path_xy for agent in pm.agent_vehicles},
)
path = pm.prediction.trajectories.get(agent.agent_id) # [n_steps, 2] world x,y [m]
Timesteps — do not mix tracking and prediction:
| YAML key | Stage | Used by |
|---|---|---|
c11_predict_delta_t |
Forecast | Default predict_delta_t on prediction objects; collision step indexing |
c15_tracking_dt |
Tracking | Kalman filter only (KalmanTracker._dt) |
8. Example: Custom World Bridge¶
from avlite.c10_perception.c11_perception_model import EGO_AGENT_ID
from avlite.c40_execution.c41_world_bridge import WorldBridge
from avlite.c30_control.c31_control_model import ControlCommandBase
from avlite.c50_common.c51_capabilities import StackCapability, WorldCapability
class MyBridge(WorldBridge):
@property
def world_capabilities(self) -> set[WorldCapability]:
return {WorldCapability.LIDAR_2D}
@property
def stack_capabilities(self) -> set[StackCapability]:
# Ground truth provided by the world (satisfies downstream stack_requirements)
return {StackCapability.LOCALIZATION}
def control_ego_state(self, cmd: ControlCommandBase, dt=0.01):
# Send control to your simulator or robot
pass
# Optional (future): multi-agent fleets — declare WorldCapability.AGENT_CONTROL
def control_agent(self, agent_id: int, cmd: ControlCommandBase, dt=0.01):
if agent_id == EGO_AGENT_ID:
return self.control_ego_state(cmd, dt=dt)
# Resolve agent, optionally convert cmd, actuate in sim
...
control_type(agent) defaults to control_type_for_agent(agent) from c38_control_mapping.py. Use world.step(dt) to advance the sim without a new command from the stack (default no-op until a bridge overrides it and the executer wires sub-stepping).
9. Export Classes¶
# __init__.py
from .my_strategy import MyPerception, MyLocalization, MyController
from .settings import PluginSettings
__all__ = ["MyPerception", "MyLocalization", "MyController", "PluginSettings"]
When you rename a module file, update the import path in __init__.py to match (e.g. from .p31_joystick_controller import JoystickController).
10. Register Your Community Plugin¶
Via GUI (recommended):
1. Open AVLite
2. Go to Config tab
3. Add entry under community plugins: my_plugin → install path (or use Install then Register from python -m avlite plugins)
4. Save profile
Double-click a community plugin in the list to view its Package Name and Settings file paths separately. Reset to Installed repopulates the list from plugin directories under the user install dir (~/.local/share/avlite/plugins/).
Via settings file (the c69_apps section of configs/<profile>.yaml, or your saved copy under ~/.config/avlite/):
c69_apps:
c62_community_plugins:
my_plugin: my_plugin # installed under ~/.local/share/avlite/plugins/
dev_plugin: ~/src/my_plugin # local dev checkout outside the plugins dir
The map value is the install path, not the settings YAML path. When a plugin lives under ~/.local/share/avlite/plugins/ (override install root with AVLITE_PLUGINS_DIR), AVLite stores the name sentinel (my_plugin: my_plugin). Paths outside that directory are stored as ~/... or an absolute path. Plugin settings always live in ~/.config/avlite/plugin_<name>.yaml, independent of the install location.
Your classes will now appear in the UI dropdowns.
Member plugins (AV-Lab)¶
The Members tab in python -m avlite plugins lists plugins from the AV-Lab
private registry. Sign in with GitHub (Device Flow) to browse and install them;
your GitHub account must have access to the registry and to each listed plugin
repository. Install and register work the same as community plugins once you are
signed in. See Member plugins in the main docs.
11. Publish to the community registry (pull request)¶
To list your plugin in every user's Community tab (python -m avlite plugins), add it to the official public registry via pull request.
Registry repository: github.com/AV-Lab/avlite-community-plugins
Before you open a PR¶
- Test locally — register the plugin on a profile (section 10) and confirm your strategies appear in the GUI dropdowns and the stack runs.
- Public Git repository — the registry clones your repo; private repos will not install for other users.
- Plugin layout — at minimum:
- Optional —
settings.pywithPluginSettingsif you have tunable parameters;requirements.txtif you depend on extra pip packages (users install these into their AVLite environment). - Do not commit a
.venvinside the plugin repo.
Registry entry¶
Fork avlite-community-plugins, add one item under plugins: in plugins.yaml, and open a pull request:
plugins:
- name: my_perception_plugin
description: One-line summary of what the plugin does
repository: https://github.com/your-org/your-plugin-repo
version: latest # or a git tag / commit SHA
author: your-org
category:
- PerceptionStrategy
| Field | Notes |
|---|---|
name |
Unique registry id; also the install folder name under ~/.local/share/avlite/plugins/. Use lowercase with underscores. |
description |
Short text in the plugin list. |
repository |
HTTPS Git URL (GitHub is supported for README preview in the browser). |
version |
latest clones the default branch; pin a tag or SHA for reproducible installs. |
author |
Display name, handle, or organization. |
category |
List of strategy types this plugin provides (see table below). Shown in the Plugins browser Category column. |
Category values (use the names from avlite-community-plugins):
| Category | Use when your plugin implements… |
|---|---|
PerceptionStrategy |
Sensing, detection, tracking, segmentation, fusion (includes monolithic perception and pipeline sub-strategies such as DetectionStrategy) |
LocalizationStrategy |
Pose estimation, SLAM-based localization |
MappingStrategy |
Map building, SLAM mapping, environment representation |
PlanningStrategy |
Global/local planners, behavior planning, decision-making |
ControlStrategy |
Vehicle controllers, actuation |
ExecutionStrategy |
Runtime execution, scheduling, orchestration |
WorldBridge |
Bridges to simulators, middleware, or external world interfaces |
A plugin can list multiple categories if it exports more than one strategy type, e.g. [PerceptionStrategy, LocalizationStrategy].
Keep entries sorted alphabetically by name if the registry already follows that convention.
Pull request checklist¶
- Plugin works when registered manually (section 10)
- Repository is public and cloneable
-
__init__.pyexports all strategy classes users should select - README explains what the plugin provides and any extra setup
- Registry
namematches how you refer to the plugin in docs - Registry
categorymatches the base class(es) you export - No secrets, large binaries, committed virtualenv, or
config/folder with plugin-local YAML profiles in the plugin repo
In the PR description, briefly state what layer(s) the plugin extends (perception, planning, control, bridge, etc.) and link to an example profile or usage steps if helpful.
After merge¶
Once the PR is merged to main, AVLite fetches the updated registry automatically the next time a user opens Plugins (python -m avlite plugins). They can Install, then Register to add the plugin to their active profile (c62_community_plugins in the c69_apps section of configs/<profile>.yaml).
You do not need a new AVLite release for registry-only changes.
Updating your listing¶
- New plugin version — push to your repo; users click Update in the Plugins browser (or reinstall). Bump
versioninplugins.yamlif you want to pin a new tag/SHA for fresh installs. - Change metadata — open another PR on avlite-community-plugins to edit
description,author,category, orversion.
12. Built-in plugin naming (pNx)¶
Built-in plugins under avlite/plugins/ use a directory name and optional module file names with a pNx prefix:
- Directory:
p{layer}{variant}_{description}— e.g.p30_controller_joystick,p40_executer_ROS2 - Module files: use the same convention when the file belongs to a specific layer — e.g.
p31_joystick_controller.py,p42_perception_node.py
The first digit after p maps to the log-panel layer toggle:
| Digit | Layer |
|---|---|
| 1 | Perception |
| 2 | Planning |
| 3 | Control |
| 4 | Execution |
| 5 | Visualization |
| 6 | Common |
The plugin directory name and module file name can differ. For example, package p30_controller_joystick may contain module p31_joystick_controller.py.
Logger names follow Python's __name__, e.g. avlite.plugins.p30_controller_joystick.p31_joystick_controller. Log routing uses the first module segment under the package (p31_joystick_controller) before falling back to the directory name.
13. Log panel filtering¶
The visualizer log toolbar provides:
- Core — master toggle for all core stack logs (
avlite.c10_*…avlite.c50_*). Does not change the per-layer checkbox states. - Plugins — master toggle for all
avlite.plugins.*logs. - Per-layer checkboxes (Perception, Planning, Control, Execution, Visualization, Common) — filter core logs and plugin logs routed to that layer.
Plugin logs are routed to a layer toggle as follows:
- Take the first module segment under the plugin package (e.g.
p31_joystick_controllerfromavlite.plugins.p30_controller_joystick.p31_joystick_controller). - If it matches
pNx, use that digit for the layer. - Otherwise fall back to the plugin directory name (e.g.
p40_bridge_carlaforcarla_bridgemodule). - If still no
pNxmatch (typical community plugins), the log is shown whenever Plugins is on.
| Logger | Module segment | Layer source |
|---|---|---|
...p30_controller_joystick.p31_joystick_controller |
p31_joystick_controller |
module → Control |
...p40_bridge_carla.carla_bridge |
carla_bridge |
package fallback → Execution |
...p40_executer_ROS2.p42_perception_node |
p42_perception_node |
module → Execution |
...sample_avlite_plugin.test_plugin |
test_plugin |
no pNx → Plugins master only |
Filtering reads a thread-safe snapshot updated on the main thread only (safe when worker threads emit logs during execution).
Base Classes Reference¶
| Base Class | Purpose | Key Method |
|---|---|---|
PerceptionStrategy |
Monolithic detection/tracking/prediction | perceive() |
DetectionStrategy |
Detection sub-strategy (used by PerceptionPipeline) |
detect() |
TrackingStrategy |
Tracking sub-strategy (used by PerceptionPipeline) |
track() |
PredictionStrategy |
Prediction sub-strategy (used by PerceptionPipeline) |
predict() |
LocalizationStrategy |
Localization | localize() |
MappingStrategy |
Mapping | TBD |
LocalPlanningStrategy |
Local planning | replan() |
GlobalPlannerStrategy |
Global planning | plan() |
ControlStrategy |
Vehicle control | control() |
WorldBridge |
Simulator integration | control_ego_state(), control_type(agent), control_agent(), teleport_agent(), get_*(agent_id=...), step() |
Apps (AppStrategy)¶
CLI and GUI entry points register via :class:~avlite.c60_apps.c61_app_strategy.AppStrategy (same auto-register pattern as perception/planning strategies). Subclass as class MyToolApp(AppStrategy), set cli_name and help, implement run(), and optionally configure_parser() for flags or nested subcommands. Built-in p50 entry classes use the *App suffix (e.g. SettingCliApp, VisualizationApp); the base framework class remains AppStrategy. Importing the module registers the app.
| App | Plugin / module | Command |
|---|---|---|
| Visualizer (default) | p60_visualizer_tk (p61_visualizer_app) |
python -m avlite |
| Settings GUI | p60_visualizer_tk (p62_setting_app) |
python -m avlite setting |
| Plugin manager | p60_visualizer_tk (p63_plugins_app) |
python -m avlite plugins |
| Headless runner | p60_headless_mode |
python -m avlite headless |
| Setting CLI | p60_setting_cli |
python -m avlite setting-cli |
Built-in p60_* plugin packages are imported at startup via bootstrap_apps() in c61_app_strategy. The merged p60_visualizer_tk package hosts shared Tk code (p64_setting_views, p65_ui_lib, settings.py) and three standalone AppStrategy entry modules. Stack core (c10–c40, c50_common) may import c61_app_strategy, c64_settings_schema, c68_paths, and c69_settings only; it must not import p60_* Tk apps.
See Also¶
Built-in plugins in avlite/plugins/ (maintained by core team):
- p60_visualizer_tk — Tk visualizer GUI, settings window (avlite setting), and plugin browser (avlite plugins)
- p60_headless_mode — Headless terminal dashboard runner
- p60_setting_cli — Terminal profile validate/describe/import/export
Additional world bridges (CARLA, Gazebo, ROS2), executers, and controllers are available as optional plugins, installed via c62_community_plugins in the c69_apps section of configs/<profile>.yaml.
Settings for built-in plugins: configs/plugin_*.yaml in the repo (same basename under ~/.config/avlite/ when saved). Community plugin settings use the same plugin_<name>.yaml basename but live only under ~/.config/avlite/ (no repo default).