ML Integration Plan for BioNav-SLAM
Outlines a plan to add ML training and inference to a bio-inspired SLAM simulation, with data collection, model zoo, and CLI modes.
What this file does
Outlines a plan to add ML training and inference to a bio-inspired SLAM simulation, with data collection, model zoo, and CLI modes.
When to use it
- Adding supervised learning to a robotics simulation project
- Refactoring a simulation to support offline training and online inference
- Creating a reproducible pipeline from data collection to model deployment
- Standardizing model interfaces across different ML frameworks
Assumes this stack
ML Integration Plan for BioNav-SLAM
Goal: refactor the project so you can easily add ML models (training + inference) that learn from simulation data (e.g., place recognition, odometry correction, loop-closure classifier, policy networks). Provide a clear pipeline: collect data → train offline → load model for inference in simulation with reproducible configs and tests.
High-level design
- Keep the simulation core (physics, Central Complex modules, planner) separate and deterministic.
- Add
bionav.mlas the ML layer: dataset creation utilities, trainer abstraction, model zoo, and an inference wrapper. - Provide a
data/folder for logged episodes (CSV / NumPy / TFRecords / Torch files). - Provide CLI flags so you can run simulation in
--collect-data,--train, or--infermodes. - Provide standardized model interface with methods:
fit(dataset, cfg),save(path),load(path),predict(obs).
Proposed repo layout
BioNav-SLAM/
├─ bionav/
│ ├─ __init__.py
│ ├─ core.py # Central Complex math, TB1, CPU4 etc.
│ ├─ sim.py # Env + run_simulation()
│ ├─ planner.py # A* / path planning
│ ├─ gui.py # visualization (thin wrapper)
│ ├─ ml.py # high-level ML trainer & model interface
│ ├─ datasets.py # dataset builder & loaders
│ ├─ io.py # save/load traces/configs
│ └─ utils.py # helpers
├─ configs/
│ ├─ experiment.yaml
├─ data/
│ └─ episodes/ # .npz or .npy logged runs
├─ models/
│ └─ saved_models/
├─ tests/
├─ bio_nav.py # CLI entrypoint
├─ requirements.txt
└─ README.md
requirements.txt (additions for ML)
numpy>=1.24
matplotlib>=3.6
pytest>=7.0
pillow>=9.0
scikit-learn>=1.2
torch>=2.0 # or replace with tensorflow if you prefer
tqdm
yaml
Key design patterns & interfaces
1) Data collection (simulation → disk)
run_simulation(..., collect=True, out_dir=...)records per-step observations and actions into an episode file (prefer.npzcontaining arrays:observations,actions,rewards,meta).- Observations are structured dictionaries turned into arrays using
datasets.py:serialize_observation(obs).
Why: offline training is easier and deterministic.
2) Dataset & loader
bionav/datasets.pyexposesEpisodeDataset(PyTorchDataset) that loads.npzfiles and yields(x, y)pairs for training.
3) Trainer & model abstraction
bionav/ml.pyexposes a simpleTrainerclass with.train(dataset, cfg)and.evaluate()plus model interface wrapper classes (e.g.,TorchModelWrapper) that implementsave/load/predict.
4) Inference in-sim
- Provide
bionav/ml_inference.pyor keep apredict_fn = model.predictreference; at each sim step callmodel.predict(observation)and use output to modify agent behavior (e.g., correct odometry, give loop-closure signal, or output action probabilities).
Example files (copy-paste ready)
bionav/datasets.py (PyTorch dataset loader)
# bionav/datasets.py
from pathlib import Path
import numpy as np
from torch.utils.data import Dataset
class EpisodeDataset(Dataset):
"""Loads .npz episode files saved by run_simulation(collect=True).
Each .npz contains: observations (N x D), actions (N x A), meta dict.
"""
def __init__(self, folder, transform=None):
self.folder = Path(folder)
self.files = list(self.folder.glob("*.npz"))
self.transform = transform
def __len__(self):
return len(self.files)
def __getitem__(self, idx):
path = self.files[idx]
data = np.load(path)
obs = data['observations']
acts = data['actions']
# default: return full time-series; training code may slice subsequences
sample = {'observations': obs.astype('float32'), 'actions': acts.astype('float32')}
if self.transform:
sample = self.transform(sample)
return sample
bionav/ml.py (trainer + simple model wrapper)
# bionav/ml.py
import torch
from torch import nn
from torch.utils.data import DataLoader
import os
class TorchModelWrapper:
def __init__(self, model: nn.Module, device='cpu'):
self.model = model.to(device)
self.device = device
def save(self, path):
os.makedirs(os.path.dirname(path), exist_ok=True)
torch.save(self.model.state_dict(), path)
def load(self, path):
self.model.load_state_dict(torch.load(path, map_location=self.device))
self.model.eval()
def predict(self, x_np):
# x_np: numpy array, shape (B, D) or (D,)
import numpy as np
self.model.eval()
with torch.no_grad():
x = torch.from_numpy(np.asarray(x_np)).float().to(self.device)
if x.dim() == 1:
x = x.unsqueeze(0)
out = self.model(x)
return out.cpu().numpy()
class Trainer:
def __init__(self, model_wrapper: TorchModelWrapper, lr=1e-3, device='cpu'):
self.w = model_wrapper
self.device = device
self.criterion = nn.MSELoss()
self.optimizer = torch.optim.Adam(self.w.model.parameters(), lr=lr)
def train(self, dataset, epochs=10, batch_size=64):
loader = DataLoader(dataset, batch_size=batch_size, shuffle=True)
for ep in range(epochs):
running = 0.0
for batch in loader:
obs = batch['observations'] # shape B x T x D OR B x D
acts = batch['actions']
# For simplicity assume B x D -> regression
obs = obs.float().to(self.device)
acts = acts.float().to(self.device)
preds = self.w.model(obs)
loss = self.criterion(preds, acts)
self.optimizer.zero_grad()
loss.backward()
self.optimizer.step()
running += loss.item()
print(f"Epoch {ep}: loss={running/len(loader):.6f}")
Note: This trainer assumes observations/actions are already preprocessed into fixed-size arrays. For sequence models (RNNs/Transformers), modify dataset to return subsequences.
Example simple MLP model (bionav/models/simple_mlp.py)
# bionav/models/simple_mlp.py
import torch.nn as nn
class SimpleMLP(nn.Module):
def __init__(self, in_dim, out_dim, hidden=[128,64]):
super().__init__()
layers = []
prev = in_dim
for h in hidden:
layers.append(nn.Linear(prev, h))
layers.append(nn.ReLU())
prev = h
layers.append(nn.Linear(prev, out_dim))
self.net = nn.Sequential(*layers)
def forward(self, x):
return self.net(x.float())
Integration: collect data from sim (sim.py changes)
- Add a
collect_episodeflag and a helpersave_episode(path, obs_list, actions_list, meta)that writes.npzfiles. - Per-step, record the observation structure (e.g.,
[x,y,theta,sensor_readings,...]) and action taken.
Suggested naming: data/episodes/expname_seed_0001.npz
Integration: run inference in sim
- After training, load model via
TorchModelWrapper.load(path)frommodels/saved_models/model.pth - Pass the
model.predict(obs_vector)output to the decision layer. For example, a trained model can produce a correcteddx, dyto fuse with CPU4.
Example CLI modes (bio_nav.py)
--mode {run,collect,train,infer}
--collect-out data/episodes/
--model-out models/saved_models/
--config configs/experiment.yaml
collect: runs N episodes saving.npzfiles.train: loads dataset and trains the model.infer: starts sim and loads model for online inference.
Unit testing & CI
- Add tests that verify dataset loader loads arrays with expected shapes
- Add a smoke test that creates a tiny model, trains for 1 epoch on a generated dataset, saves and reloads it, and runs
predict.
Example quick-run workflow
python bio_nav.py --mode collect --episodes 50 --out data/episodes/# gather datapython bio_nav.py --mode train --config configs/experiment.yaml# trains modelpython bio_nav.py --mode infer --model models/saved_models/latest.pth# run sim with ML
Next steps I can do for you right now (pick any):
- Generate the exact
bionav/datasets.py,bionav/ml.py,bionav/models/simple_mlp.pyfiles as ready-to-paste code (I already included them here). - Create
bio_nav.pyCLI wrapper code that wires--modeand the three workflows. - Create a small example
collect -> train -> inferdemo using synthetic data so you can run end-to-end. - Make a PR-style diff or zip with the new files.
What's inside
8 sections, 3 code examples, 1 repo layout diagram, 1 requirements list, 1 CLI spec
Change this for your project
- Replace
BioNav-SLAMwith your project name - Replace
bionavwith your package name - Replace
ATHARVA316-DEV/BioNav-SLAM-A-Bio-Inspired-Robotic-Navigation-and-SLAM-Simulationwith your repository URL - Replace
configs/experiment.yamlwith your config path
Where it goes
A standard operating procedure. Keep where the team or agent running the process will find it.
Worth borrowing
- Separate simulation core from ML layer for deterministic data collection
- Standardized model wrapper interface (fit, save, load, predict) for swapping frameworks
- CLI modes (collect, train, infer) that wire the full pipeline without manual steps
Related Documents
Comprehensive AI Assistant Tools Reference
Lists 80+ tools with MCP server associations, bulk support, parallel capability, resource impact, and execution type for AI agent workflows.
iOS Deployment Guide
Walks through setting up an iOS development environment, building a Tauri app for iOS, and publishing to the App Store or alternative channels.
How to Add Resources to Your FastMCP Server
Teaches how to add static and dynamic MCP resources to a FastMCP server, with six ready-to-copy examples for a GitHub crawler.
PCI Compliance Guide
Explains PCI DSS compliance via tokenization, lists forbidden and allowed data, and provides code examples for BigCommerce and Stripe.