Skip to main content
Start with your robot’s calibrated profile and change only the fields you need. Navigation configuration controls the robot-side runtime: motion limits, camera calibration, localization, geometry, collision handling, controller tuning, recovery, and recording. It is different from the map and route settings in the mission editor.

Choose the right kind of change

A Nav instance is shared by clients. Any settings on an attach to an existing instance are rejected, even if they are identical. Stop does not release the instance. Read its state, coordinate with its owner, then shutdown() before constructing a replacement. Never use replacement as an implicit way to interrupt someone else’s mission.

1. Inspect what your robot uses

This attaches without changing settings and prints selected effective values. nav.config is a plain dictionary, not a live editable config object. It can be None on a runtime that does not report its configuration.
With no explicit settings, Nexus uses the robot’s GRID_NAV_CONFIG file when configured; otherwise PointNav selects the profile matching the robot’s registry type. Bundled profile names currently include r1pro, vision60, go2, g1, and dr02. A bundled profile’s presence is not proof that a particular deployment has navigation provisioned or its required sensors.

2. Override a few fields

Use dotted field paths and native Python values. For example, below we lower the maximum forward speed and increase the localization query timeout while keeping the rest of the robot’s selected profile. Run this replacement only when you own the current navigation workflow.
The override names are max_linear_vel and localization.hloc_query_timeout_s, not mission arguments. Unknown dotted paths are errors. Paths traverse nested dictionaries, not list indices: replace an entire list when changing polygon points or similar fields. Values are copied and validated. Geometry propagation fills selected unset/default fields; it does not reliably refresh every derived value in an exported configuration. See the geometry limitations below.

Precedence

For a newly constructed Nav, settings are applied in this order:
  1. Dataclass/schema defaults fill omitted fields.
  2. The selected robot profile or explicit config supplies values.
  3. A selected YAML/profile omni section is merged.
  4. Dotted overrides replace existing fields.
  5. Explicit runtime keywords such as backend and record take precedence.
The robot-side GRID_SAFETY_MODE environment variable is applied when a YAML/mapping is loaded and is read again by safety construction. In this runtime it can therefore supersede an explicit safety.mode override. Have the operator remove that environment override or make it agree with the intended mode; inspecting nav.config alone does not prove which mode the later safety builder will select. A full cfg replaces profile selection; it is not merged with the robot’s calibrated profile. A tiny config such as {"max_linear_vel": 0.2} fills everything else from generic schema defaults, including camera and robot defaults. Use dotted overrides for a small change.

3. Start a complete config from a known-good snapshot

This alternative preserves your current resolved configuration, changes two fields, and saves a JSON copy on your computer. JSON is also useful to agents because field values and types are explicit. Submit the dictionary over Nexus; you do not need PointNav installed locally.
The saved file contains calibration and robot-side asset paths. Keep it associated with that robot and deployment. A config is not a map, mission, credential file, or way to install missing robot assets.

4. Supply a YAML file on the robot

For deployment-managed configuration, install a YAML file on the robot’s filesystem and pass its absolute path. Nexus does not upload your laptop’s file when given a string.
This is an alternative constructor after the old Nav has been released. config= is an alias for cfg=; do not pass both. Do not combine an explicit config with profile or config_dir. The following excerpt shows the shape, not a complete robot calibration:
Download a complete R1Pro omni example and the configuration JSON Schema. Use the matching installed robot profile as your starting point; the R1Pro example is not a generic config for other robots. The field reference lists every schema field and distinguishes generic defaults from profile-specific values.

Advanced: export and validate on the robot

Customers use grid_nexus_client.nav and the nav.config export above from their laptop. The following commands are for an operator on the robot (or a deployment environment with its matching grid-pointnav installed). Export the profile without opening robot hardware:
Use your actual robot type. Select --no-omni for a profile’s base settings. To validate an edited YAML and inspect the resolved result:
--generate-config exits before robot connection and mission execution. The loader validates types and cross-field constraints. Structural JSON Schema checks alone do not enforce all calibration, geometry, and mode rules. Export the matching installed schema on that same machine:

Paths, overlays, and calibration

  • YAML must have a mapping root; duplicate keys are rejected. Use nested mappings, not dotted keys inside a YAML file.
  • Relative model/calibration paths declared in YAML resolve relative to that file on the robot. Paths in a dictionary resolve from the robot process’s working directory. Prefer explicit absolute paths or supported package://grid_pointnav/... asset references.
  • Dotted path overrides currently bypass part of the asset/calibration resolver. For a changed calibration file or package-relative asset path, use a complete YAML/mapping configuration and verify its loaded camera metadata rather than assuming a dotted path change reloads intrinsics.
  • A top-level omni: mapping is a YAML/profile overlay with the same nested shape. Explicit YAML configs apply it only with omni=True; dictionaries must already contain the resolved settings and cannot use that overlay.
  • Profile-based R1Pro construction applies its omni section by default when present; omni=False selects its base profile. Other profiles default to their base settings.
  • robot.query_intrinsics is a 3×3 matrix. query_image_size and query_resolution are [width, height]; an empty resolution preserves native pixels. T_body_camera and T_body_lidar are flat 16-element row-major transforms. Use the frame conventions of your calibrated profile.
  • Keep camera intrinsics, distortion, extrinsics, LiDAR frame flags, self-masking, and robot geometry consistent. Changing a motion cap does not recalibrate a camera or shrink the physical robot.
For a custom profile directory, put a file named after the profile (for example r1pro.yaml) on the robot and use this alternative:
An explicit config_dir wins over GRID_POINTNAV_CONFIG_DIR, then the bundled directory. The profile’s robot.robot_type must match its name.

Geometry, safety zones, and controller timing

These are alternative construction recipes. Shut down an existing Nav before creating another one with different settings; they do not retune an attached instance in place.

Body geometry and derived values

robot_geometry.footprint_polygon describes the measured body-frame hull: metres, X forward and Y left. Supply at least three finite, non-collinear [x, y] vertices enclosing the body origin. Body geometry uses a convex hull; footprint_padding_m adds clearance around it. For profiles without a polygon, inscribed_radius_m supplies the circular fallback. Inspect the root geometry together with the controller and safety sections:
The loader copies some derived geometry into DWA, MPPI and the safety barrier. Those copies can become stale after changing the root shape in an exported config. Numeric backend fields do not generally accept None as an inheritance setting. Start geometry changes from the matching installed profile and review all consumer values, including dwa.footprint_polygon, dwa.footprint_padding, dwa.robot_radius, both controller inflation radii, and safety.barrier_footprint_polygon. A nonpositive root inflation_radius_m asks the loader to derive an inflation radius and store the resolved number. Exporting that number does not retain an automatic relationship for later geometry edits. Explicit backend tuning may differ intentionally; inflation is distance from an obstacle, not extra body padding.
The current runtime has known inconsistencies in DWA costmap radii/padding and MPPI padded-corner radius calculations. Config loading does not reject all malformed footprints. A successful config load is not evidence that a custom body shape is collision-safe. Geometry changes require checking the actual controller footprint and clearance in simulation or robot qualification.
With an articulated projection model, live joint geometry updates the shape at runtime; the static polygon is its configured starting shape.

Collision zones

safety.mode="gate" selects the legacy forward/reverse and swept-barrier filter. Its front/rear bands, predictive rectangle, and barrier settings apply to that mode. safety.mode="nav2" selects the planar collision monitor, including lateral motion; its settings are under safety.nav2. Omni MPPI requires the Nav2 mode. safety.enabled controls filtering. Nav2 zone coordinates are body-frame metres, unlike mission keepouts, which use map coordinates. Choose type="polygon", "circle", or "velocity_polygon":
  • A polygon uses ordered points describing a simple shape. Concave zones are supported. Supply finite vertices without duplicate edges, zero area, or self-intersections; the current loader does not reject every invalid shape.
  • A circle uses a positive radius.
  • use_robot_footprint=True is for polygon zones. It uses the padded measured body and follows live footprint updates. Leave points unset.
  • A velocity polygon uses velocity_polygons, each with points, inclusive linear_min/max and theta_min/max. In holonomic mode, linear range is speed magnitude and direction is constrained by direction_start_angle and direction_end_angle in radians. A start angle above the end wraps across π. First matching subpolygon wins; an uncovered command retains the last shape. The current runtime can pass an uncovered command before any shape has been selected. Cover the full intended velocity range and include an unconditional stop zone rather than relying on an initially unmatched zone.
Each zone selects action_type: stop zeros the command; slowdown multiplies it by slowdown_ratio in [0, 1]; limit scales it to the linear and angular caps; approach scales it using predicted time to contact; none does nothing. min_points is the positive count of obstacle returns required to trigger. The trigger/release counts debounce consecutive evaluations, not seconds. For approach, simulation_time_step must be positive and no greater than time_before_collision. This is a minimal body-stop policy. Replacing polygons removes all previous zones, including a profile’s slowdown and approach zones; include every zone you intend to retain:
The independent Nav2 filter uses processing_frequency_hz. source_timeout limits scan age, cmd_vel_timeout limits command age, and stop_pub_timeout controls continued zero publication. A zero source/command timeout disables that age check. base_shift_correction compensates scan-time robot motion. The legacy navigation-loop safety.lidar_max_points cap uses stride sampling; zero evaluates the full scan. Sampling can discard obstacle returns and alter min_points decisions; the independent Nav2 actuator filter uses the full scan.

MPPI timing precedence

controller_frequency_hz=0 inherits control_hz. The solve rate is that rate divided by positive integer command_decimation; intermediate ticks hold the last command. Native model_dt is the reciprocal of the solve rate. Use explicit time_steps for ordinary configuration. In the current runtime, prediction_horizon_s is used only in a legacy environment-override path, not as a general duration control. With GRID_MPPI_DECIM unset in the robot process, this example gives 30 prediction steps of 0.1 seconds:
legacy_g1_env_overrides=True enables the legacy GRID_MPPI_* controls. When GRID_MPPI_HZ or GRID_MPPI_DECIM is present in that mode, a duration can derive the step count unless GRID_MPPI_TSTEPS is supplied. One current exception is GRID_MPPI_DECIM: it applies even when the legacy flag is false. Leave the flag false and have the operator unset GRID_MPPI_DECIM for the explicit timing recipe above.

Progress, recovery, and smoothing

The controller’s progress checker uses movement radius, optional heading change, and a time allowance under dwa_pipeline or mppi_pipeline. The stall detector tracks sustained blocking/no progress. The separate stuck section owns mission-level timeout and bounded recovery rearming; these are different stages, not interchangeable thresholds. recovery.mode="none" disables recovery. The current simple and adaptive values both enable the configured recovery policy. A nonempty schedule wins; otherwise profile.enabled=True generates a schedule from the profile. profile.adaptive_goals separately enables perception-derived goals. pose_align applies when the final waypoint requests a heading. For velocity smoothing, mode="legacy" uses scalar acceleration limits; mode="nav2" uses [vx, vy, wz] vectors. Acceleration and deadband values are nonnegative; deceleration vector entries are nonpositive. min_velocity must not exceed max_velocity on any axis. feedback="CLOSED_LOOP" uses measured velocity; OPEN_LOOP uses the smoother’s previous output.

Per-mission options

These serializable options affect one run without rewriting nav.config: Choose these after starting/localizing and reviewing your mission. This example moves the robot and checks its terminal result.
Do not put controller fields such as max_linear_vel directly in run_mission. Change them at construction through overrides. Object-valued internal worker/test hooks are not portable Nexus inputs.

Recording

record="default" (and None) selects nav,pose,cmd,gt. record="off" disables bags. record="all" adds the heavier lidar,costmap,rgb,odom_fast channels. A comma-separated string selects only the named channels, so use "nav,pose,cmd,gt,rgb" to add images to the default set. Unknown channel names are ignored with a warning; check spelling. Recording is best-effort and requires robot-side GRX. Bags are robot-side artifacts; the navigation proxy does not expose a bag download method. The live viewer’s terminal-log download is a different artifact. Turning recording off does not turn off Nexus live telemetry.

Polygon constraints

The current runtime enforces polygon keepout and positive cost zones in its local rolling costmap. These are not editor drawing tools and do not make the cloud planner constraint-aware. A route can still be globally planned through a zone and then blocked locally; review the route accordingly. The mapping has version: 1, optional id (default empty string), revision (nonnegative integer, default 0), zones (default empty list), and semantic_rules (must be empty today). Each zone requires a unique, nonempty id, type, and polygon of at least three map-frame XY pairs. A cost zone also requires cost from 1 to 252; keepout zones omit it. This example only creates the policy dictionary. Replace the empty polygon with coordinates from the active map before using it.
After review, pass it as constraints=constraints to a mission call. The broader stored contract also names preferred, speed_limit, planner_penalty, max_linear_mps, and semantic rules, but the local runtime rejects these unsupported policies rather than silently applying part of them. There is no public remote method to edit constraints mid-run.

Finish and verify

After constructing a new Nav, inspect nav.config again, then start the map and verify localization before executing a mission. To finish, use nav.shutdown() followed by robot.shutdown(). See the API contract for runtime errors and the configuration field reference for the complete shape.