Simple navigationΒΆ
Run this example first in the SLAM β localization walkthrough. It lists
navigation configs that support SLAM, starts the navigation engine, builds up
the map, navigates to a target pose, then saves the map as example-map for
Localization with a saved map.
Pass on_feedback / onFeedback to receive
NavigationFeedback updates. Each callback includes
distance_remaining (distanceRemaining in TypeScript), navigation_time,
number_of_recoveries, and current_pose.
"""SLAM navigation example β saves example-map for navigation-localization."""
import math
import time
from olo import Client
from olo.locomotion import PlanarMotion
from olo.navigation import Nav2ErrorCode, NavigationFeedback
from olo.platform import NavigationMode, NavigationObservedState
from olo.spatial import Pose
EXAMPLE_MAP_NAME = "example-map"
def on_feedback(feedback: NavigationFeedback) -> None:
# Do something with the feedback
pass
with Client() as client:
configs = client.platform.navigation.get_configs(NavigationMode.SLAM)
if not configs:
raise RuntimeError("No navigation configs support SLAM mode")
config = configs[0]
print(f"Using navigation config: {config.name = }, {config.id = }")
# Start navigation engine (namespace resolves like client.robot())
client.platform.navigation.start(mode=NavigationMode.SLAM, config_id=config.id)
last_state = None
deadline = time.time() + 60
while time.time() < deadline:
info = client.platform.navigation.deployment()
state = info.observed.state if info.observed else None
if state != last_state:
print(f"Navigation engine: {state}")
last_state = state
if state == NavigationObservedState.READY:
break
if state == NavigationObservedState.FAILED:
raise RuntimeError(f"Navigation failed to launch: {info.observed.error_message}")
time.sleep(2)
else:
raise TimeoutError(f"Navigation engine did not become ready within 60s (last state: {last_state})")
# Move the robot to build a map
robot = client.robot()
robot.locomotion.move(PlanarMotion(x=1.0, yaw=2 * math.pi))
# Once the map has some substance, send the robot a pose goal
target = Pose.from_xy_yaw(1.5, 0.5, 1.5708)
result = robot.navigation.navigate_to(target, on_feedback=on_feedback)
print(f"Navigation outcome: {result.outcome.value} ({result.reason})")
if result.nav2_error_code:
print(f"Error: {Nav2ErrorCode.name_for(result.nav2_error_code)}")
# Persist the SLAM map for reuse
saved = client.platform.navigation.save_map(EXAMPLE_MAP_NAME)
print(f"Saved map: {saved.name} [{saved.id}]")
/** SLAM navigation example β saves `example-map` for navigation-localization.ts. */
import { connect } from "olo/web";
import { nav2ErrorCodeName, type NavigationFeedback } from "olo/navigation";
import { Pose } from "olo/spatial";
const EXAMPLE_MAP_NAME = "example-map";
function onFeedback(_feedback: NavigationFeedback): void {
// Do something with the feedback
}
const client = connect();
const configs = await client.platform.navigation.getConfigs("slam");
if (configs.length === 0) {
throw new Error("No navigation configs support SLAM mode");
}
const config = configs[0];
console.log(`Using navigation config: name=${config.name}, id=${config.id}`);
// Start navigation engine (namespace resolves like client.robot())
await client.platform.navigation.start({
mode: "slam",
configId: config.id,
});
let lastState: string | undefined;
const deadline = Date.now() + 60_000;
while (Date.now() < deadline) {
const info = await client.platform.navigation.deployment();
const state = info.observed?.state;
if (state !== lastState) {
console.log(`Navigation engine: ${state}`);
lastState = state;
}
if (state === "ready") break;
if (state === "failed") {
throw new Error(`Navigation failed to launch: ${info.observed?.errorMessage}`);
}
await new Promise((r) => setTimeout(r, 2000));
}
if (lastState !== "ready") {
throw new Error(`Navigation engine did not become ready within 60s (last state: ${lastState})`);
}
// Move the robot to build a map
const robot = await client.robot();
await robot.locomotion.move({ x: 1.0, y: 0, yaw: 2 * Math.PI });
// Once the map has some substance, send the robot a pose goal
const target = Pose.fromXyYaw(1.5, 0.5, 1.5708);
const result = await robot.navigation.navigateTo(target, { onFeedback });
console.log(`Navigation outcome: ${result.outcome} (${result.reason})`);
if (result.nav2ErrorCode) {
console.log(`Error: ${nav2ErrorCodeName(result.nav2ErrorCode)}`);
}
// Persist the SLAM map for reuse
const saved = await client.platform.navigation.saveMap(EXAMPLE_MAP_NAME);
console.log(`Saved map: ${saved.name} [${saved.id}]`);