Part of World Models Handbook
Explains how coordinate frames, depth estimation, SLAM, occupancy grids, and neural fields give world models geometric state that stays stable under egomotion.
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
Geometry, Mapping, and 3D/4D State
Imagine a delivery robot entering a cluttered lobby. Two cameras on its head see a chair from slightly different viewpoints, producing two very different arrays of pixels. A second later, the robot turns, and the pixel array changes extensively again. Yet the chair itself has not moved. If the robot's world model stores predictions over pixels, almost every "state" it tracks changes whenever the agent so much as rotates its head. If instead it tracks where the chair is, in a frame that does not move with the robot, the chair's physical pose stays stable while observations flow past it. That pose changes when something in the world acts on the chair; the robot's belief about the pose can also change when new evidence arrives. Separating physical state from belief state is not an aesthetic preference. It lets physical transitions represent events in the world, belief updates represent acquired information, and neither be confused with artifacts of the observer's own motion.
This is the core promise of geometric state. Building on the discussion of sufficient state from Part III, geometry provides allocentric representations that can remain fixed under egomotion and egocentric representations that transform equivariantly under known pose changes. Building on the body schema from Part III, the agent's own pose becomes part of the state, the hinge that connects "where I am" to "what I see." Pose lets the agent factor the geometric-motion component of observation change into two causes: the observer moved, or the scene moved. Illumination, visibility, exposure, calibration, sensor noise, and other image-formation effects remain additional causes of changing observations. Separating observer motion from scene motion is a longstanding organizing idea in robotics perception, and it remains useful when learned world models make frames and action effects explicit. Geometry serves four roles here: a state format, a sensor model, a source of self-supervised training signal, and a practical substrate for planning. These roles connect influential classical estimators with influential learned geometric representations.
A note on what "better" means here, because it will recur throughout. Geometric representations can be evaluated along four partly independent axes. Predictive fidelity: does the model reproduce future observations accurately? Representation quality: does the internal 3D structure match the true scene structure, even where no camera ever looked? Uncertainty quality: do the confidences attached to geometric estimates (depth variances, occupancy probabilities, pose covariances) accurately reflect what is and is not known? Decision usefulness: can a planner consume the predictions and act well? A representation can excel on one axis and fail another. Photorealistic view synthesis can have high predictive fidelity with poor uncertainty quality; a blurry but well-calibrated occupancy map may be far more decision-useful than a sharp overconfident one. Keeping these axes separate is the discipline this chapter tries to enforce.
In this chapter we work through the geometric toolkit in four layers. First, coordinate frames and camera geometry: how a 3D world projects into 2D observations, and what that projection destroys. Second, depth, pose, and scene flow: how to recover 3D quantities from observations. Third, SLAM, occupancy grids, and semantic maps: how to accumulate geometric state over time under uncertainty. Fourth, neural fields and dynamic 3D representations: how modern continuous, learnable scene representations replace and extend classical grids. Throughout, we distinguish what a geometric model predicts from how a decision-making agent uses those predictions.
Coordinate Frames and Camera Geometry
This section covers the vocabulary that everything else depends on: frames of reference, rigid transforms, and the pinhole camera model that connects 3D points to pixel observations. The material is classical, but it deserves careful treatment, because many practical failures in 3D perception and learned world modeling trace back to frame bookkeeping done carelessly: a rotation applied in the wrong direction, a translation expressed in the wrong frame, a depth confused with a range.
Frames, Rigid Transforms, and Homogeneous Coordinates
A frame is a coordinate system attached to something: the world (allocentric), the robot's body (egocentric), a camera, an object. Every geometric statement is implicitly relative to a frame, and much of practical 3D robotics is bookkeeping about which frame each quantity lives in. The phrase "the chair is at position " is incomplete on its own; it only becomes a claim about the world once we say whose coordinates those are. In a world model, this incompleteness is dangerous, because learned networks can silently internalize whatever frame dominated their training data, and then fail unpredictably when the deployment frame convention differs.
Rigid transforms move points between frames. A rigid transform is a rotation followed by a translation; it preserves distances and angles. Physically, this is exactly the transformation relating any two frames that are bolted to rigid bodies, which is why it suffices for cameras mounted on robots, hands holding objects, and sensors on vehicles. We write the transform from world frame to camera frame as:
where is a rotation matrix (, ) and is a translation vector. The two constraints defining have physical meaning: orthogonality says the camera's axes stay perpendicular, and unit determinant says the axes keep a right-handed orientation, which excludes reflections. The subscript convention reads naturally as "the rotation taking points expressed in into points expressed in ." The set of all such transforms forms the group , and composing them is just matrix-style chaining: walking from the camera frame to the body frame to the world frame composes two transforms into one. This composition property is what makes transform graphs workable in practice. A robot typically maintains a tree of frames, camera-to-gripper, gripper-to-wrist, wrist-to-base, base-to-world, and any point can be moved between any two frames by composing the transforms along the connecting path.
The awkward part of this notation is that rotations and translations do not combine into a single matrix multiplication on 3-vectors. Composition becomes messy: , and inverting means remembering that the translation must be rotated back before being negated. Homogeneous coordinates fix all of this. We append a 1 to every point, making it a 4-vector, and write the transform as one matrix:
Now composition is ordinary matrix multiplication, , and inversion is (mostly) a structured transpose-like operation: for a rigid transform, , which needs only the already-available rather than a general matrix inverse. When the transform is a pure frame-to-frame map like , the inverse is the reverse map ; software can obtain it with the structured rigid-transform inverse or cache it as an implementation choice. Homogeneous coordinates also let us treat points at infinity uniformly, which matters because projection is about to send finite 3D points onto a 2D plane where direction, not distance, survives. A direction is represented by a homogeneous vector whose final coordinate is zero. Under projection, a family of parallel 3D lines meets at a vanishing point, while the directions contained in a plane form a horizon line. The projective framework handles these ideal elements with the same algebra as ordinary points rather than as special cases.
Camera parameters split into two groups. Extrinsic parameters describe a camera's pose relative to another frame. For a rigidly mounted camera, the camera-to-body mount transform is a fixed calibration and part of the agent's body schema. The world-to-camera pose used above is instead , so it changes as the body pose changes. Intrinsic parameters describe how the camera maps its own frame to pixels: focal length, principal point, lens distortion. For a stable imaging configuration, intrinsics are usually treated as fixed and estimated offline by calibration, for example by imaging a known checkerboard pattern from many angles and solving for the parameters that best explain the observed line curvature and corner positions. They must be updated or estimated online when zoom, focus, cropping, stabilization, resolution, temperature, or other image-formation changes alter the effective camera model. Keeping these quantities separate matters because a world model must predict the evolving body or world-relative pose while the rigid mount calibration and intrinsics normally stay fixed within that stable configuration. When a learned model implicitly entangles them, it will fail to transfer across cameras, or worse, it will fail to transfer across a zoom or a lens swap on the same robot.
The Pinhole Camera
The pinhole model is the workhorse idealization of a camera. Light passes through a single point (the optical center). The physical sensor lies behind that center and forms an inverted image. The conventional computer-vision model used below instead intersects rays with a virtual image plane in front of the center; the image-coordinate convention absorbs the physical inversion and gives the positive-sign projection equations. Lens distortion is a common geometric departure that calibration can estimate, but real image formation also includes finite-aperture blur, aberrations, motion blur, rolling shutter, sampling, exposure, and other effects that may need explicit models for the task at hand. An ideal visible 3D point in camera coordinates , with positive optical-axis depth , projects to pixel coordinates:
The equations have a direct physical reading. Dividing by is the perspective effect: for fixed lateral coordinates and , increasing positive depth moves the projection toward the principal point. The focal lengths scale normalized ray coordinates and , the tangents of the off-axis ray angles, into pixels. Treating pixel offset as directly proportional to angle is a small-angle approximation. A longer focal length means a given lateral offset at depth produces a larger pixel displacement. The principal point accounts for the fact that the optical axis does not usually pierce the sensor exactly at its center. In matrix form, stacking the whole pipeline from world to pixel:
This compact expression is worth internalizing because it separates cleanly: the matrix does the world-to-camera rigid motion, the calibration matrix does the camera-to-pixel mapping, and the result is a single linear operation in homogeneous coordinates. Homogeneous coordinates isolate this linear projective transform from the nonlinear perspective division that follows; real cameras add lens distortion and other nonidealities outside the displayed model.
The tilde and the carry real meaning: is a homogeneous 3-vector, and means equality up to multiplication by any nonzero scale. Converting that homogeneous image vector to ordinary pixel coordinates then requires dividing by its third coordinate. That division is the nonlinear heart of perspective, and it is where information dies. Up to that division, the mapping from world point to image point is linear, which is why much of multi-view geometry can be developed with linear algebra, and why the division step is exactly where reconstruction difficulty concentrates.
Look at what the projection discards. The pixel depends only on the direction of , not its length. The camera-frame points and land on exactly the same pixel because both and match. The perspective division by has erased the overall scale of the camera-frame point. Every observation is a ray from the optical center, and the observation alone cannot tell you where along the ray the world is. Formally, the two pixel coordinates provide two scalar constraints on a three-dimensional point, leaving a one-parameter family of locations along the ray. This single fact drives most of the rest of the chapter: recovering depth requires either extra information (a second viewpoint, a depth sensor, a learned prior) or extra assumptions. Whenever a system appears to get depth from a single image for free, one of these three is hiding somewhere, and it is worth finding out which.
To see the collapse concretely, the next cell places several points along a single viewing ray at different depths, projects each one, and also compares axial depth against Euclidean range for off-axis points.
import numpy as np
## Points along one viewing ray through the optical center: direction fixed, depth varies.
depths = np.array([1.0, 2.0, 4.0, 8.0])
ray_dir = np.array([0.5, 0.3, 1.0])
points_on_ray = depths[:, None] * ray_dir[None, :]
K_demo = np.array([[200.0, 0.0, 160.0], [0.0, 200.0, 120.0], [0.0, 0.0, 1.0]])
uv_ray = (K_demo @ (points_on_ray / points_on_ray[:, 2:]).T).T[:, :2]
## Axial depth vs Euclidean range for off-axis points at fixed depth Z = 3 m.
Z_fixed = 3.0
lateral = np.linspace(0.0, 3.0, 40)
euclid_range = np.sqrt(lateral**2 + Z_fixed**2)
pixel_u = 200.0 * lateral / Z_fixed + 160.0

Also note that is depth along the optical axis, not Euclidean distance to the point. Conflating the two is a common source of subtle bugs. For a point well off-axis, the Euclidean range can be substantially larger than the axial depth, and a stereo algorithm, a lidar, and a learned depth network may each report a slightly different one of these quantities by convention. When fusing sensors or comparing predictions against ground truth, always check which convention each source uses.
Depth and Its Disambiguation
Given the ray ambiguity above, how do agents recover depth? There are three broad strategies, and they differ in what they assume and what they guarantee. It is worth being explicit about the source of depth information in each case, because that source determines the failure modes.
- Stereo and multi-view geometry: two cameras with a known baseline see the same point from two positions. The point's depth is the only value consistent with both observations. Geometrically, each pixel defines a ray. For a correct correspondence from compatible calibrated pinhole cameras, noise-free rays meet at the scene point in a nondegenerate configuration. For a rectified pair with parallel optical axes and a horizontal baseline , horizontal disparity and focal length in pixels obey . Arbitrary calibrated viewpoints instead require triangulation from their projection matrices. The rectified-pair inverse relationship has important operational consequences. A larger baseline improves first-order depth precision when focal length in pixels and disparity uncertainty are controlled. More pixels across the same field of view can also help when optical quality, calibration, correspondence quality, and disparity uncertainty in pixel units do not degrade. Resolution alone cannot recover information lost to blur or matching error. Distant points have tiny disparity and are hard to localize, which is why stereo depth maps are accurate nearby and noisy in the distance.
The inverse relationship is easiest to trust when plotted: the next cells evaluate the stereo equation over a depth range for two baselines.
import numpy as np
f_px = 200.0
depth_grid = np.linspace(1.0, 30.0, 200)
## First-order depth-error estimate from fixed half-pixel disparity uncertainty,
## using differential error propagation for Z = fB/d.
disp_err_px = 0.5
depth_err_B05 = depth_grid**2 * disp_err_px / (f_px * 0.3)
depth_err_B08 = depth_grid**2 * disp_err_px / (f_px * 0.8)
There is also an engineering trade: a wide baseline improves far-field depth but worsens the correspondence problem for near objects, which appear at very different positions in the two images and may not be visible to both cameras at all. Finally, stereo requires that the same surface point be identifiable in both views, which fails on textureless surfaces, specular highlights, and occluded regions. This is the correspondence problem. Once calibration, baseline, resolution, and synchronization are adequate for the operating regime, correspondence quality is a major remaining source of stereo error; whether it dominates depends on that regime.
- Active sensing: depth cameras may use structured light or optical time of flight, lidar times the return of laser light, and radar estimates range from radio-frequency propagation delay, beat frequency, or phase. A time-of-flight lidar sends a pulse and measures the return delay; a structured-light camera projects a known pattern and infers depth after decoding or matching the pattern in the camera image. These sensors replace unconstrained passive-image correspondence with controlled pattern decoding, propagation-time, beat-frequency, or phase estimation. In return, they introduce cost, weight, range, interference, and material-dependent failure modes. They also return range rather than depth in many cases, so converting to a camera-frame depth map requires care with conventions. For a world model, active sensors change the learning problem: when depth is measured rather than inferred, the model's depth predictions can be trained against direct metric measurements rather than only against multi-view consistency. That is a substantially stronger supervision signal, although it still contains calibration error, measurement noise, missing returns, and sensor-specific failure modes.
- Learned monocular depth: a network predicts depth from a single image by exploiting learned priors about the world: sizes of familiar objects, ground-plane regularities, shading and texture gradients. The network is effectively performing inference over the missing dimension using statistical knowledge of what scenes usually look like. This is powerful but is fundamentally prior-driven, and we must be precise about what it guarantees. Where the prior holds, predictions can be good; where it is violated, an unusual object, an unfamiliar scale, an adversarial texture, an ordinary point-estimate output can be confidently wrong without signaling the problem. Uncertainty-aware models can expose predictive uncertainty, confidence, or invalid regions, but those signals are not guaranteed to remain calibrated under distribution shift.
A single calibrated image does not determine a scene merely up to one global scale: each observed pixel defines a ray with its own unknown depth. Perspective makes that per-point ambiguity immediate because any positive multiple of a camera-frame point has the same ratios and . Monocular depth networks therefore produce depth only to the extent that learned scene priors or additional constraints couple those otherwise independent ray depths. For a world model feeding a planner, this distinction is not academic: "the door is 0.9 m wide" and "the door looks like the doors that were 0.9 m wide in training" are different claims with different failure modes. The second can fail when object sizes or camera configurations differ from training, without the image alone exposing the error. A single global scale ambiguity arises in calibrated monocular multi-view reconstruction under the usual rigid-scene and known-calibration assumptions: scaling the reconstructed scene and camera translations together leaves the images unchanged. In that setting, one known metric anchor, such as a known object size or an inertial or wheel-odometry scale, can fix the global factor. It still cannot resolve arbitrary per-pixel depths in an otherwise unconstrained single image.
Triangulation generalizes stereo to arbitrary camera arrangements. Given two projection matrices and a pixel correspondence, the 3D point can be estimated from the two projection constraints. With noisy pixels the rays generally fail to meet exactly, but different estimators optimize different objectives: the linear DLT code below minimizes an algebraic homogeneous residual, while closest-ray and nonlinear reprojection-error methods solve different geometric objectives. Let's make the DLT construction concrete with code.
We define a pinhole camera, project a small cube of 3D points from two poses, and inspect the parallax between the two images.
import numpy as np
def look_at(camera_pos, target, up=np.array([0.0, 0.0, 1.0])):
"""Build a world-to-camera rotation, choosing a fallback up axis if needed."""
forward = target - camera_pos
forward_norm = np.linalg.norm(forward)
if forward_norm < 1e-12:
raise ValueError("camera_pos and target must be distinct")
forward = forward / forward_norm
right = np.cross(up, forward)
right_norm = np.linalg.norm(right)
if right_norm < 1e-12:
# Choose the coordinate axis least aligned with forward. This preserves
# a valid frame when the requested up vector is collinear with view.
fallback = np.eye(3)[np.argmin(np.abs(forward))]
right = np.cross(fallback, forward)
right_norm = np.linalg.norm(right)
right = right / right_norm
up_cam = np.cross(forward, right)
return np.stack(
[right, up_cam, forward], axis=0
) # camera axes in world coords
def project(points_world, R, t, K):
"""Project visible world points; camera-frame optical depth must be positive."""
points_cam = (R @ points_world.T).T + t
z = points_cam[:, 2]
if np.any(z <= 0):
raise ValueError(
"Pinhole projection requires positive camera-frame depth Z."
)
uv = (K @ (points_cam / z[:, None]).T).T
return uv[:, :2], z
## Intrinsics: 320x240 image, focal length 200 px, principal point at the center
K = np.array([[200.0, 0.0, 160.0], [0.0, 200.0, 120.0], [0.0, 0.0, 1.0]])
camera_cx = K[0, 2]
camera_cy = K[1, 2]
## A cube of 3D points near the origin
corners = np.array(
[[x, y, z] for x in (-0.4, 0.4) for y in (-0.4, 0.4) for z in (0.1, 0.9)],
dtype=float,
)
## A rectified stereo pair: parallel optical axes and a lateral 0.8 m baseline.
## This holds camera orientation fixed so disparity isolates inverse depth.
pos1 = np.array([-0.4, 0.0, -2.5])
pos2 = np.array([0.4, 0.0, -2.5])
R1, R2 = np.eye(3), np.eye(3)
t1, t2 = -R1 @ pos1, -R2 @ pos2
uv1, z1 = project(corners, R1, t1, K)
uv2, z2 = project(corners, R2, t2, K)Cube corner depths from camera 1: 2.600 to 3.400 m Mean pixel shift between the two views: 54.3 px
Every corner shifts between the two views, and the shift is larger for nearer points. That shift is exactly the signal stereo reconstruction exploits. Note also the translation trick used in the code: the world-to-camera translation is , where is the camera's position in world coordinates, which is the standard way to convert a camera pose into the transform the projection equations need. Now let's invert the projection: given noisy pixel correspondences in both views and known calibration, recover each point's depth by linear triangulation. For each view with projection matrix , a world point must satisfy and , where is row . Each such equation states that the observed pixel lies on the ray predicted by the projection, which, after clearing the perspective division, becomes a homogeneous linear equation in the unknown 3D point. Two views give four equations; the homogeneous least-squares solution is the right singular vector associated with the smallest singular value.
def projection_matrix(R, t, K):
return K @ np.hstack([R, t.reshape(3, 1)])
def triangulate(uv_a, uv_b, P_a, P_b):
"""Linear triangulation: one 3D point per pair of pixel correspondences."""
points = []
for (u_a, v_a), (u_b, v_b) in zip(uv_a, uv_b):
A = np.vstack(
[
u_a * P_a[2] - P_a[0],
v_a * P_a[2] - P_a[1],
u_b * P_b[2] - P_b[0],
v_b * P_b[2] - P_b[1],
]
)
_, _, Vt = np.linalg.svd(A)
points.append(Vt[-1][:3] / Vt[-1][3])
return np.array(points)
P1, P2 = projection_matrix(R1, t1, K), projection_matrix(R2, t2, K)
## Realistic pixel noise, then triangulate and compare against true depth
rng = np.random.default_rng(0)
uv1_noisy = uv1 + rng.normal(0, 0.5, uv1.shape)
uv2_noisy = uv2 + rng.normal(0, 0.5, uv2.shape)
X_est = triangulate(uv1_noisy, uv2_noisy, P1, P2)
depth_est = ((R1 @ X_est.T).T + t1)[:, 2]
err_cm = np.abs(depth_est - z1) * 100Mean triangulated depth error: 2.34 cm at 3.0 m mean depth Worst corner error: 6.96 cm
With the seeded half-pixel noise, two rectified views 0.8 m apart produce about 2.3 cm mean depth error and about 7 cm worst-corner error in this synthetic setup. The calculation uses no learned object-category prior, but it still assumes calibrated camera models, known poses, correct correspondences, a compatible scene across the observations, and the DLT noise objective. This is the quantitative backbone behind "multi-view consistency": agreement across viewpoints is strong evidence of correct structure when calibration, correspondences, noise sources, and the scene model are sufficiently independent and valid. Shared calibration, synchronization, correspondence, or rolling-shutter errors can instead make several views agree on the same wrong structure. We will return to this when we discuss why novel-view consistency is such a valuable training signal for world models. The same arithmetic also reveals the weakness: the errors here grow roughly with the square of depth and inversely with baseline, so the same pipeline at 25 m with a 0.8 m baseline would be far less precise, which is why outdoor systems demand longer baselines or active sensors.

Depth, Pose, and Scene Flow
Recovering geometry from observations involves three coupled estimation problems: depth (where points are), pose (where the sensor or object is), and scene flow (how points move). They are coupled because you usually need one to estimate the others: motion of the camera explains part of the image change, motion of the world explains the rest. To convert a set of depth measurements into a world-frame map you need the sensor pose; to estimate the sensor pose from point clouds you need the geometry of the surfaces around you; to tell whether a surface moved you need to know how much of its apparent motion came from the sensor. There is no fixed order of operations that breaks this loop cleanly. Practical systems break it with approximations, iteration, or priors, and the quality of the resulting geometry depends on how honest the system is about which variable was held fixed while estimating the others.
Estimating Pose
This section covers two common pose-estimation cases, distinguished by the correspondences available: 3D-to-2D and 3D-to-3D.
- 3D-to-2D (perspective-n-point): given known 3D points and their pixel projections, solve for the camera pose. Each known 3D point together with its observed pixel constrains the pose, because the point must lie on that pixel's ray, and enough rays must intersect at a common camera position and orientation. This is what happens when a robot localizes against a known map, or when it estimates an object's pose from detected keypoints. For a calibrated perspective camera, P3P uses three nondegenerate correspondences but can yield multiple pose solutions, so a fourth correspondence is commonly used to disambiguate them. Other camera models and degenerate point configurations change the requirement. Closed-form and iterative solvers exist, and robust variants handle outliers. In deployed pose estimation, robustness to correspondence outliers is often at least as important as nominal inlier accuracy: a single mis-detected keypoint, if trusted, can drag the whole pose estimate far away, so deployed systems pair the solver with RANSAC-style hypothesis testing that fits the pose to random minimal subsets and keeps the one supported by the most correspondences.
- 3D-to-3D (Procrustes / Kabsch): given two point clouds that are related by a rigid transform, the best-fit rotation and translation have a closed-form solution via SVD. This is the core step inside iterative closest point (ICP) registration and inside many odometry pipelines. ICP illustrates how a chicken-and-egg problem is handled by alternation: correspondences between the clouds are guessed from the current transform estimate, the optimal transform for those correspondences is computed in closed form, and the two steps repeat until convergence. Each half of the loop is easy precisely because the other half is temporarily fixed, an alternation also used by expectation-maximization. An EKF addresses coupling differently: it performs sequential prediction and a joint linearized Bayesian update rather than alternating between fixed optimization blocks.
The Kabsch solution is worth knowing because it recurs everywhere. Given matched source points and target points , first compute their centroids and the centered versions and :
- Compute the cross-covariance .
- Take the SVD .
- The optimal rotation is , where corrects the sign if (reflections are not rigid transforms).
- The translation is .
A few remarks on why this works and when it does not. Centering both clouds first removes the translation from the problem, leaving a pure rotation to be found; the cross-covariance summarizes how source directions map to target directions, and the SVD extracts the orthogonal matrix best aligning them. The determinant correction in step 3 is essential: without it, the least-squares optimum occasionally wants to be a reflection, which is geometrically illegal, and the correction projects back to the nearest legal rotation. Finally, the closed form is only as good as its correspondences. Kabsch assumes each source point is already matched to the correct target point; if the matching is wrong, the transform will be confidently wrong, which is why ICP wraps this solver in an outer loop that revises the matching.
Scene Flow
Scene flow is a per-point 3D motion field expressed in one specified coordinate frame. In a world frame, for example, . Sensor observations instead arrive in the distinct time-indexed frames and . Directly subtracting their numerical coordinate triples gives an apparent coordinate displacement, not a geometric vector in one frame. A geometric displacement requires transporting one endpoint into the other's frame first. Scene flow is the 3D generalization of optical flow and the bridge between per-frame geometry and temporal prediction.
Scene flow is where geometry meets dynamics, and it deserves careful decomposition. When a sensor moves through a static world, all apparent sensor-coordinate change is explained by one rigid transform: the egomotion. This is a remarkably strong structural prior, because a single transform accounts for the coordinate change of potentially millions of observed points at once. Camera and object rigid transforms compose rather than adding as independently defined displacements. A precise destination-frame residual transports the time- point from into before subtraction:
where the homogeneous transform is applied before taking the three-vector difference. A static world point has zero residual under the correct egomotion transform; nonzero residual captures object motion or modeling error in .
A world model without an explicit separation must learn observer-induced change jointly with scene dynamics. It may misattribute that change or generalize poorly unless action or pose conditioning, model capacity, data, and observability make egomotion predictable. Explicitly decomposing a global rigid component from the residual is therefore a useful sanity check in dynamic-scene perception, not a prerequisite for every successful predictor. The residual contains the dynamics of walking people, articulating arms, and falling objects, along with any uncompensated estimation error. It is also, as you might expect from Part III's object-centric chapter, a strong cue for segmentation: points that share a residual motion tend to belong to the same object. Coherent residual motion can support segmentation before object classification, although it does not by itself establish object identity.
Let's estimate a rigid transform from a moving point cloud and look at what remains.
## A point cloud observed at two times: the object rotates and translates,
## and the measurements carry sensor noise.
rng = np.random.default_rng(11)
P0 = rng.uniform(-0.3, 0.3, size=(100, 3))
theta = np.deg2rad(15.0)
R_true = np.array(
[
[np.cos(theta), -np.sin(theta), 0.0],
[np.sin(theta), np.cos(theta), 0.0],
[0.0, 0.0, 1.0],
]
)
t_true = np.array([0.12, 0.05, 0.0])
noise = 0.008
P1 = (R_true @ P0.T).T + t_true + rng.normal(0, noise, P0.shape)
def kabsch(P_src, P_dst):
"""Best-fit rigid transform mapping P_src onto P_dst."""
c_src, c_dst = P_src.mean(axis=0), P_dst.mean(axis=0)
H = (P_src - c_src).T @ (P_dst - c_dst)
U, _, Vt = np.linalg.svd(H)
D = np.diag([1.0, 1.0, np.sign(np.linalg.det(Vt.T @ U.T))])
R = Vt.T @ D @ U.T
t = c_dst - R @ c_src
return R, t
R_est, t_est = kabsch(P0, P1)
flow_raw = P1 - P0
flow_res = P1 - ((R_est @ P0.T).T + t_est)Rotation error: 0.0100 Translation error: 0.0006 Mean raw flow magnitude: 0.1389 m Mean residual flow magnitude: 0.0127 m
Despite the sensor noise, the recovered transform matches the ground truth closely, and the residual flow magnitude is an order of magnitude below the raw flow. The averaging effect is what makes this work: with one hundred points, independent per-point noise partially cancels in the cross-covariance, so the estimated transform is much more accurate than any individual point correspondence. Rigid decomposition can provide this noise-averaging benefit when the matches are correct and well distributed and their errors are sufficiently independent and unbiased. More points do not cure correlated bias, outliers, or degenerate geometry.


Read the two panels as a diagnostic. The raw flow is large and spatially structured: it encodes the object's rigid rotation and translation in the static sensor frame, plus measurement noise. The residual collapses to the noise floor, confirming that a single rigid transform explains everything. The diagnostic has a clear decision rule. If the residual collapses everywhere, the observed correspondences support a single shared rigid-motion hypothesis within the noise level. That does not prove there is one physical object, exclude unobserved structure, or guarantee that a single object-level state suffices. If some cluster of points keeps a large coherent residual, it is evidence for independently moving structure and a candidate motion segmentation. Calibration error, rolling shutter, nonrigid deformation, mismatches, or multiple objects sharing motion can produce similar patterns, so the candidate must be validated before it becomes an object or dynamics model. If the residual is large but incoherent, the matching or the rigidity assumption itself is failing, and no amount of averaging will fix it. Note also that this procedure silently used correspondences: we knew which point at time was which point at time . In real data, establishing those correspondences is its own estimation problem, and matching errors show up as outlier residuals that robust estimation must reject.
Before leaving scene flow, it helps to see the egomotion coupling as a picture. The next cell uses a new static-world point cloud and asks what happens when the estimated camera motion is wrong by a small rotation: every point acquires a coherent residual.
import numpy as np
## Sensor egomotion: a small true camera rotation between frames.
eps_rot = np.deg2rad(4.0)
R_ego = np.array(
[
[np.cos(eps_rot), -np.sin(eps_rot), 0.0],
[np.sin(eps_rot), np.cos(eps_rot), 0.0],
[0.0, 0.0, 1.0],
]
)
t_ego = np.array([0.05, -0.03, 0.0])
## Static-world points observed by the moving sensor. The noise floor is kept
## small (0.002 m) so the coherent residual produced by a 1-degree egomotion
## error stands out clearly above it.
rng_ego = np.random.default_rng(21)
static_pts = rng_ego.uniform(-0.8, 0.8, size=(100, 3))
static_next = (
(R_ego @ static_pts.T).T
+ t_ego
+ rng_ego.normal(0, 0.002, static_pts.shape)
)
## Correct egomotion removal leaves only noise; a 1-degree error leaves a coherent residual.
R_fix, t_fix = kabsch(static_pts, static_next)
res_correct = static_next - ((R_fix @ static_pts.T).T + t_fix)
err_rot = np.deg2rad(1.0)
R_wrong = np.array(
[
[np.cos(err_rot), -np.sin(err_rot), 0.0],
[np.sin(err_rot), np.cos(err_rot), 0.0],
[0.0, 0.0, 1.0],
]
)
fitted_next = (R_fix @ static_pts.T).T + t_fix
wrong_next = (R_wrong @ fitted_next.T).T
res_wrong = static_next - wrong_next
mag_correct = np.linalg.norm(res_correct[:, :2], axis=1).mean()
mag_wrong = np.linalg.norm(res_wrong[:, :2], axis=1).mean()
A word of caution: this decomposition assumed the sensor was static. In practice the sensor moves, and egomotion must be estimated and removed first, which is exactly the localization problem of the next section. Errors in egomotion leak directly into false "object motion." If the estimated camera motion is wrong by a small rotation, every static point acquires a small coherent residual that can masquerade as a slow-moving object. This coupling is why dynamic-scene perception and localization are usually solved together or in an alternating scheme, and why any claim of "object detection by motion" should be checked against the quality of the egomotion estimate underneath it.
Simultaneous Localization and Mapping
This section covers how an agent builds and maintains geometric state over time: the coupling between localization and mapping, the classical EKF solution, occupancy grids for dense maps, and semantic extensions. The unifying theme is accumulation under uncertainty: single-frame estimates are noisy and partial, and the SLAM family of methods is about fusing many of them into a consistent whole without letting errors compound.
Why Localization and Mapping Are Coupled
To build a map from a moving sensor, you need to know where each observation was taken. To know where you are, it helps to have a map to match against. This chicken-and-egg structure is the defining feature of SLAM: simultaneous localization and mapping. It is worth spelling out why neither half alone suffices. Odometry, the integration of motion measurements, gives localization without a map, but without an absolute or map-relative correction its uncertainty accumulates and dead-reckoning drift is generally unbounded over long horizons. Individual zero-mean errors can cancel on a particular realization; it is the growing uncertainty, and systematic bias when present, that makes uncorrected odometry unreliable. Matching against a map gives map-relative localization that can bound or correct accumulated odometric drift, though map, calibration, association, and environmental errors remain. In an unknown environment without an external absolute reference such as a surveyed map, GNSS, motion capture, or known landmarks, the SLAM solution is to estimate pose and map together and let each constrain the other. Formally, the agent wants the joint posterior:
over the entire trajectory and the map , given all observations and controls. Full-trajectory SLAM is a smoothing problem because today's map depends on where the robot was yesterday. EKF-SLAM, by contrast, is an online filtering formulation over the current pose and persistent map state. When the robot realizes, upon recognizing a landmark, that its pose from an hour ago was wrong, every observation taken since then was attached to the map at the wrong place and must be corrected retroactively. This is why SLAM is fundamentally harder than the filtering problems of Part II: the state whose history matters keeps growing. In Part II we met Bayesian filtering over a belief state; SLAM is what happens when the belief state grows to include a model of the world itself, and the state and the map become statistically coupled through every shared observation. The connection to world models is direct: SLAM is the classical instance of maintaining a persistent, action-conditioned belief over scene structure, updated by every observation and corrected by every act of re-observation.
EKF-SLAM
The extended Kalman filter approach makes the belief explicit. For the planar example below, the robot pose is and each landmark is a point in . The state vector stacks that pose and all landmark positions:
The key structural fact is that is dense: observing a landmark from a new pose correlates the landmark estimate with the pose estimate and, through the pose, with every other landmark. This density is not an accident or an implementation nuisance; it is the mathematical expression of the chicken-and-egg coupling. If the pose is uncertain, then a landmark's inferred location inherits that uncertainty, and so does every other landmark placed relative to the same pose. Each measurement update tightens the whole web. Algorithmically, each step is the familiar predict-then-update cycle, with the motion model linearized in the pose block and the measurement model (range and bearing to a landmark) linearized jointly in the pose and landmark blocks. Linearization is needed because both models are nonlinear in the pose, through sines and cosines of the heading and through the arctangent in the bearing, and the EKF evaluates the local Jacobian at the current mean. As everywhere with extended Kalman filtering, the linearization is only trustworthy within a neighborhood, so large innovations or long un-observed stretches can push the estimate to where the linearization misleads.
Let's implement a compact EKF-SLAM. To keep the demo focused on the estimation machinery, we make three explicit simplifications: the robot follows a known circular path with noisy odometry, measurements are range-bearing to landmarks with known data association (we are told which landmark each measurement corresponds to; the real problem of deciding this is the association problem), and landmark initialization uses the first measurement directly. Each simplification hides a real difficulty. The association problem, deciding whether this observation is of a previously mapped landmark or a new one, is a discrete inference problem layered on top of the continuous one, and a single wrong association can corrupt the entire dense covariance. Initialization from a single range-bearing reading is possible only because the sensor directly measures both range and angle; with a camera, a first sighting constrains only a ray, and the landmark's depth stays unknown until parallax accumulates. The time schedule also matters: the filter consumes the measurements at without advancing the state, then performs one odometry prediction from to before applying the measurements indexed by . Thus every stored estimate, measurement set, and ground-truth pose with the same index refers to the same simulation time. Because the demo has only relative range-bearing observations and unknown landmarks, its global frame is not identifiable from the measurements. The imperfect initial pose prior supplies the simulator-frame anchor, so the raw pose and map errors below are unaligned and depend on that gauge choice.
## Simulation setup: a differential-drive robot circling a small landmark field.
rng = np.random.default_rng(3)
dt, T = 0.15, 200
v_true = 0.45
landmarks = np.array(
[
[1.2, 1.8],
[-1.5, 1.6],
[0.0, 0.2],
[-1.8, -1.4],
[1.6, -1.6],
[0.3, 2.6],
]
)
## Ground-truth trajectory: explicit-Euler approximation to radius-2 m circular motion
truth = np.zeros((T, 3))
truth[0] = [2.0, 0.0, np.pi / 2]
for t in range(1, T):
x, y, th = truth[t - 1]
truth[t] = [
x + v_true * np.cos(th) * dt,
y + v_true * np.sin(th) * dt,
th + (v_true / 2.0) * dt,
]
def wrap(angle):
"""Wrap an angle to [-pi, pi)."""
return (angle + np.pi) % (2 * np.pi) - np.pi
def measure(state, lm):
d = lm - state[:2]
return np.array(
[np.hypot(d[0], d[1]), wrap(np.arctan2(d[1], d[0]) - state[2])]
)
sig_r, sig_b = 0.05, 0.01 # range and bearing noise
z_all = np.full((T, len(landmarks), 2), np.nan)
for t in range(T):
for j, lm in enumerate(landmarks):
if measure(truth[t], lm)[0] < 4.0:
z_all[t, j] = measure(truth[t], lm)## EKF-SLAM: joint state is [pose, landmark_1, ..., landmark_M]
n = 3 + 2 * len(landmarks)
mu = np.zeros(n)
mu[:3] = truth[0] + np.array([0.15, -0.15, 0.05]) # imperfect initial pose
Sigma = np.eye(n) * 1e-6
Sigma[:3, :3] = np.diag([0.1, 0.1, 0.05])
initialized = np.zeros(len(landmarks), bool)
est_traj = np.zeros((T, 3))
lm_err = np.full(T, np.nan)
for t in range(T):
# z_all[0] belongs to the initial state. For later indices, advance once
# from t-1 to t before consuming the measurement generated from truth[t].
if t > 0:
# --- Predict with noisy odometry ---
v_odo = v_true + rng.normal(0, 0.03)
w_odo = v_true / 2.0 + rng.normal(0, 0.15)
x, y, th = mu[:3]
mu[:3] = [
x + v_odo * np.cos(th) * dt,
y + v_odo * np.sin(th) * dt,
wrap(th + w_odo * dt),
]
F = np.eye(n)
F[0, 2] = -v_odo * np.sin(th) * dt
F[1, 2] = v_odo * np.cos(th) * dt
Sigma = F @ Sigma @ F.T
Sigma[:3, :3] += np.diag(
[(0.03 * dt) ** 2, (0.03 * dt) ** 2, (0.15 * dt) ** 2]
)
# --- Update with each observed landmark ---
for j in range(len(landmarks)):
if np.isnan(z_all[t, j, 0]):
continue
z = z_all[t, j] + rng.normal(0, [sig_r, sig_b])
sl = slice(3 + 2 * j, 5 + 2 * j)
if not initialized[j]:
# First sight: augment both the landmark mean and its covariance.
r, phi = z
bearing_world = phi + mu[2]
c, s = np.cos(bearing_world), np.sin(bearing_world)
mu[sl] = mu[:2] + r * np.array([c, s])
J_pose = np.array([[1.0, 0.0, -r * s], [0.0, 1.0, r * c]])
J_meas = np.array([[c, -r * s], [s, r * c]])
R_meas = np.diag([sig_r**2, sig_b**2])
landmark_cross = J_pose @ Sigma[:3, :].copy()
Sigma[sl, :] = landmark_cross
Sigma[:, sl] = landmark_cross.T
Sigma[sl, sl] = (
J_pose @ Sigma[:3, :3] @ J_pose.T + J_meas @ R_meas @ J_meas.T
)
initialized[j] = True
continue
d = mu[sl] - mu[:2]
r = np.hypot(d[0], d[1])
phi = wrap(np.arctan2(d[1], d[0]) - mu[2])
H = np.zeros((2, n))
H[0, 0], H[0, 1] = -d[0] / r, -d[1] / r
H[0, sl] = (d[0] / r, d[1] / r)
H[1, 0], H[1, 1], H[1, 2] = d[1] / r**2, -d[0] / r**2, -1.0
H[1, sl] = (-d[1] / r**2, d[0] / r**2)
innov = z - np.array([r, phi])
innov[1] = wrap(innov[1])
S = H @ Sigma @ H.T + np.diag([sig_r**2, sig_b**2])
K = Sigma @ H.T @ np.linalg.inv(S)
mu = mu + K @ innov
mu[2] = wrap(mu[2])
Sigma = (np.eye(n) - K @ H) @ Sigma
est_traj[t] = mu[:3]
if initialized.all():
lm_err[t] = np.linalg.norm(
mu[3:].reshape(-1, 2) - landmarks, axis=1
).mean()
pose_err = np.linalg.norm(est_traj[-1, :2] - truth[-1, :2])Gauge-anchored final pose error: 0.172 m Gauge-anchored final heading error: 0.1195 rad Gauge-anchored mean landmark error: 0.455 m Landmark-error coverage: 157 stored states, first index 43
The filter starts with a wrong pose and unknown landmarks. It first consumes the time-zero observations, then keeps every predict-update result aligned with the truth and measurements at the same index. Every measurement couples a landmark to the current pose; nonzero pose-landmark cross-covariances let later measurement updates adjust correlated initialized landmarks along with the pose. At first observation, the pose Jacobian transfers existing pose and state uncertainty into the new landmark covariance and its cross-covariances, while the measurement Jacobian adds range-bearing noise to the landmark's own covariance block. This is the "simultaneous" in SLAM: pose and map remain jointly estimated rather than one being treated as known. Across the 200 synchronized stored states (the initial state followed by 199 motion intervals), the final unaligned simulator-frame errors are 0.172 m for position, 0.1195 rad for heading, and 0.455 m for mean landmark position. The landmark-error time series begins only after all landmarks are initialized: index 43 through 199, or 157 stored states. These values are gauge-dependent because the imperfect initial pose prior is the only global-frame anchor; they demonstrate coupling within that chosen frame rather than absolute localization accuracy or monotonic convergence. The odometry predicts where the robot is, landmark observations disagree slightly with the mapped world, and the Kalman gain distributes the disagreement between pose and landmarks according to their modeled uncertainties. The dense covariance keeps those shared uncertainties explicit; it does not by itself guarantee a consistent estimator, which also depends on initialization, linearization, data association, and the noise model.


EKF-SLAM is a beautiful teaching model but has a real limitation: the covariance has entries, and every update touches all of them. For a few dozen landmarks this is trivial; for the hundreds of thousands of features in a building-scale map it is prohibitive, and the linearization of a single joint filter over so many variables is fragile besides. Large-scale systems therefore moved to graph-based SLAM (factor graphs, pose graphs): pose estimates become nodes, measurements become edges, and the full problem is solved by nonlinear least squares, incrementally and with relinearization. The graph formulation changes the computational structure in an important way: measurement factors are sparse and local before elimination, and sparse linear algebra makes building-scale problems tractable. In incremental solvers, a new factor can limit re-elimination to an affected Bayes-tree region, although fill-in and propagated dependencies may make that region broader than the factor's immediate variables. The other essential ingredient at scale is loop closure: when the robot recognizes a place it has seen before, a valid association adds a long-range constraint between revisited poses. After successful graph optimization, that factor can reduce and redistribute accumulated drift. It does not guarantee global consistency in the presence of false associations, calibration error, weak observability, or local minima. Geometrically, loop closure supplies information that the chain of local odometry edges lacks, and the least-squares solve balances the new factor against the other measurements across the trajectory.
The endpoint effect is easy to demonstrate at small scale. The next cell simulates noisy odometry around a closed path, then applies a deliberately simple proxy for one loop-closure constraint: it forces the endpoint back to the start and distributes that endpoint error along the trajectory. This is not a pose-graph optimizer, but it isolates what the long-range endpoint constraint contributes.
import numpy as np
rng_lc = np.random.default_rng(7)
T_lc, dt_lc, v_lc = 240, 1.0, 0.052 # circle radius ~2 m in 240 steps
truth_lc = np.zeros((T_lc, 2))
ang = np.linspace(0.0, 2 * np.pi, T_lc)
truth_lc[:, 0] = 2.0 * np.cos(ang)
truth_lc[:, 1] = 2.0 * np.sin(ang)
## Odometry follows the true tangent increments with accumulated heading bias
## and small step-length noise.
bias = np.cumsum(rng_lc.normal(0, 0.02, T_lc))
drift = np.zeros((T_lc, 2))
drift[0] = truth_lc[0]
for t in range(1, T_lc):
truth_step = truth_lc[t] - truth_lc[t - 1]
step = np.linalg.norm(truth_step) + rng_lc.normal(0, 0.003)
head = np.arctan2(truth_step[1], truth_step[0]) + bias[t]
drift[t] = drift[t - 1] + step * np.array([np.cos(head), np.sin(head)])
## Loop closure: at the final step, snap the end error to zero and distribute
## it uniformly along the trajectory (equal-mass correction, tie-free).
end_err = truth_lc[-1] - drift[-1]
frac = np.linspace(0.0, 1.0, T_lc)[:, None]
closed = drift + frac * end_err
Recognition-based loop closure is itself an inference problem, often approached with learned or hand-crafted place descriptors followed by geometric or probabilistic verification. False loop closures are especially dangerous because a wrong long-range constraint can warp an otherwise consistent map.
Occupancy Grids
Landmarks are sparse. For planning, agents often want a dense answer to a dense question: for each cell of space, what is the probability it is occupied? Collision checking and path planning must reason about every point the robot might sweep through; detected features alone are insufficient. A landmark map tells you where distinctive things are; an occupancy map estimates where space is free, occupied, or unknown and provides a key input to collision checking and path planning. Occupancy grids discretize space into cells and maintain, per cell, a Bernoulli belief. Two strong assumptions concern the map itself, and it is important to state them:
- Cell independence: the map posterior is approximated as factorizing across cells conditional on the pose and measurement history. This is clearly false at boundaries, where adjacent cells belong to the same surface, but it buys an enormous simplification: instead of one inference problem over the joint map, we get a grid of tiny independent problems.
- Static world: occupancy does not change over time, so evidence can be accumulated indefinitely. This is what allows the filter to integrate over the whole history, and it is also what breaks when furniture moves.
The standard recursive update also conditions on a known or estimated sensor pose and treats measurements as conditionally independent given the map, pose, and inverse sensor model. Correlated rays or pose errors violate that approximation and can make repeated evidence accumulate too confidently.
Under these map and measurement assumptions, each cell admits a small binary filter, and the standard trick is to run it in log-odds form. For occupancy probability , define . Bayes updates multiply odds, which become additions in log space; the update for cell given observation is:
The first term is the inverse sensor model: given "this ray passed through here and stopped there," how much does that raise or lower each cell's occupancy? Rays mark traversed cells as likely free and their endpoint as likely occupied. Everything before a valid endpoint is evidence against occupancy because the measurement indicates that the beam traversed those cells before returning from the endpoint. The endpoint is evidence for occupancy because something returned or stopped the beam there. The subtraction of the prior log-odds prevents repeatedly re-adding prior belief on every update; without it, a cell would drift toward the prior's preference every time any ray touched it, even a completely uninformative one. Clipping keeps probabilities from saturating at 0 or 1, preserving the ability to revise beliefs later. This last detail is easy to dismiss and important to keep: a cell that has saturated at "certainly free" cannot absorb future evidence that it is occupied, and in any environment where the map might be wrong or the world might change, certainty is a liability.
Log-odds turn Bayes multiplication into addition, make extreme probabilities representable without floating-point underflow, and make the update a simple per-cell increment. Converting back with a sigmoid recovers probability estimates from the accumulated log-odds; whether those estimates are calibrated depends on the prior, sensor model, dependence assumptions, and empirical validation. The same trick reappears throughout probabilistic state estimation, anywhere a binary variable is updated by many small pieces of evidence.
The deeper lesson for world-model builders is what this filter does with negative evidence. A cell being consistently observed as free is information, just as real as an obstacle. The ray that traveled through a cell and kept going has testified that nothing solid was there, and after enough such rays the cell's probability drops far below the prior. Learned world models must therefore be evaluated for whether they distinguish unknown space from sensor-supported free space. Occupancy grids are a reminder that an observed ray traversal is evidence of free space under the sensor model. Mere absence of a measurement is not automatically free-space evidence, because it may reflect occlusion, field of view, dropout, or missing coverage. A state representation that cannot distinguish "unknown" from "known empty" will mislead any planner that relies on it.
Let's build a small occupancy map from simulated lidar.
## Ground-truth world at fine resolution, belief at coarse resolution
fine_res, coarse_res, world = 200, 50, 10.0
def to_fine(x):
return int((x + world / 2) / world * fine_res)
def to_coarse(x):
return int((x + world / 2) / world * coarse_res)
gt = np.zeros((fine_res, fine_res), bool)
## A wall segment, a box, and a pillar (rows index y, columns index x)
gt[to_fine(0.0) : to_fine(2.0), to_fine(-1.0) : to_fine(1.0)] = True
gt[to_fine(-3.0) : to_fine(-1.5), to_fine(2.0) : to_fine(3.5)] = True
gt[to_fine(2.8) : to_fine(3.2), to_fine(-3.2) : to_fine(-2.8)] = True
poses = [
(-4.2, -4.2, 45),
(0.0, -4.5, 90),
(4.2, -4.2, 135),
(-4.5, 0.0, 0),
(4.5, 0.0, 180),
(0.0, 4.5, -90),
]
max_range, step = 6.0, 0.05
def cast_ray(x, y, angle):
"""March a ray through the ground-truth grid; return stop distance and hit flag."""
dx, dy = np.cos(angle), np.sin(angle)
d = step
while d < max_range:
px, py = x + d * dx, y + d * dy
ix, iy = to_fine(px), to_fine(py)
if not (0 <= ix < fine_res and 0 <= iy < fine_res):
return d, False
if gt[iy, ix]:
return d, True
d += step
return max_range, False
## Log-odds belief grid
belief = np.zeros((coarse_res, coarse_res))
l_free = np.log(0.30 / 0.70)
l_occ = np.log(0.85 / 0.15)
l_clip = 5.0
raw_free_step_samples = 0
free_cell_updates = 0
ray_measurements = 0
for rx, ry, rdeg in poses:
for k in range(61): # 61 rays spanning a 180-degree field of view
ray_measurements += 1
ang = np.deg2rad(rdeg) + np.deg2rad(-90 + 3 * k)
d, hit = cast_ray(rx, ry, ang)
# The fine marcher samples more densely than the coarse belief grid.
# Deduplicate coarse cells so one ray contributes at most one free
# likelihood increment per cell. If the ray hit, reserve its endpoint
# cell for the single occupied increment.
endpoint_cell = None
if hit:
px, py = rx + d * np.cos(ang), ry + d * np.sin(ang)
endpoint_cell = (to_coarse(py), to_coarse(px))
free_cells = []
seen_on_ray = set()
for i in range(1, int(d / step)):
raw_free_step_samples += 1
px, py = rx + i * step * np.cos(ang), ry + i * step * np.sin(ang)
cx, cy = to_coarse(px), to_coarse(py)
cell = (cy, cx)
if not (0 <= cx < coarse_res and 0 <= cy < coarse_res):
continue
if cell == endpoint_cell or cell in seen_on_ray:
continue
seen_on_ray.add(cell)
free_cells.append(cell)
assert len(free_cells) == len(seen_on_ray)
assert endpoint_cell is None or endpoint_cell not in seen_on_ray
for cy, cx in free_cells:
belief[cy, cx] = np.clip(belief[cy, cx] + l_free, -l_clip, l_clip)
free_cell_updates += len(free_cells)
if endpoint_cell is not None:
cy, cx = endpoint_cell
belief[cy, cx] = np.clip(belief[cy, cx] + l_occ, -l_clip, l_clip)
occupancy_prob = 1.0 / (1.0 + np.exp(-belief))Each ray now contributes at most one free increment to each coarse cell it traverses, and a valid hit contributes one occupied increment to its endpoint cell instead of also marking that cell free. This per-ray deduplication is part of the inverse sensor model: the m ray-marching step locates intersections in the fine ground-truth grid, but it is not a source of repeated independent measurements for a m belief cell.
Note the deliberate asymmetry in these illustrative sensor-model constants: a hit marks its endpoint cell occupied with fairly high confidence ( near 1.7), while one ray's traversal through a coarse cell marks that cell free more weakly ( near ). This example therefore treats one occupied endpoint measurement as stronger evidence than one free-cell traversal measurement. Whether that asymmetry matches a real sensor depends on its beam model, cell size, incidence angle, material response, return behavior, and calibration. The ratio of these two numbers controls how the map balances commission errors (marking free space occupied) against omission errors (marking occupied space free), so tuning it has direct planning consequences.
Ray measurements: 366 Raw fine-step free-space samples: 32943 Unique non-endpoint coarse-cell updates: 9840 Deduplication factor: 3.3479x
The consequence of the two constants is easiest to see as evidence accumulation curves: how many observations of each kind it takes to move a cell's probability away from the 0.5 prior before the implemented log-odds clipping bounds turn further identical evidence into a plateau.
import numpy as np
n_obs = np.arange(0, 21)
l_free_demo = np.log(0.30 / 0.70)
l_occ_demo = np.log(0.85 / 0.15)
free_logits = np.clip(n_obs * l_free_demo, -l_clip, l_clip)
occ_logits = np.clip(n_obs * l_occ_demo, -l_clip, l_clip)
prob_free_seq = 1.0 / (1.0 + np.exp(-free_logits))
prob_occ_seq = 1.0 / (1.0 + np.exp(-occ_logits))


The reconstructed map records occupied boundary cells for all three obstacles, but notice the structure of what it does not know: obstacle interiors, cells behind obstacles, and regions no ray ever entered sit at or near the prior probability 0.5 unless another ray supplies evidence. This shadowing is not a bug. It is the honest representation of perspective dependence, and it is precisely what a naive "render the world from the last frame" world model loses. A rendered frame shows surfaces that happened to be visible; it has no way to say that the region behind the pillar is unverified, and a planner reading it has no way to ask. This distinction supports information-aware planning: a planner can prefer to gather information before committing when its objective explicitly penalizes uncertainty or rewards information gain. This is an early instance of a theme that will recur throughout the book: a state representation with honest uncertainty does not just support estimation, it actively shapes behavior, driving exploration and information gathering as rational responses to what the state admits it does not know.
Semantic Maps
Occupancy answers "is something here?" Most tasks also need "what is here?" A robot that knows a region is occupied but not whether it is a table, a person, or a pile of boxes can still choose a conservative detour or gather more information. Occupancy alone cannot choose well among all task-specific responses, such as whether waiting or interaction is appropriate. Semantic maps attach class distributions to geometric elements, either per cell (Bayesian kernel semantic fusion: each labeled observation casts a kernel of evidence into the grid) or per object in a landmark-style map. The per-cell version treats every classified pixel or point as a noisy categorical observation of the cell it lands in, and fuses those observations with the same Bayesian accumulation machinery as occupancy; the per-object version instead maintains discrete object hypotheses with class posteriors, which is more compact and more natural for manipulation but requires solving the object segmentation and data association problems first. A prominent representation in autonomous-driving research is 3D semantic occupancy: a volumetric grid where every cell carries both occupancy and class, effectively fusing detection and mapping into one representation. Its appeal is that it answers, in a single queryable structure, both the geometric question a planner asks and the semantic question a policy asks, without requiring objects to have been detected as objects at all. Semantic maps introduce new failure modes that pure geometry avoids: class priors can override evidence (the map "knows" tables do not float), and semantic errors accumulate through categorical, often correlated likelihoods rather than exactly like geometric errors. Multi-view semantic fusion can improve a class estimate, but it lacks the same direct metric constraint that triangulation provides for depth. Two cameras seeing the same surface from different angles can cross-validate a depth estimate; classifiers seeing the same object from different angles may share biases and agree on a wrong label with high confidence. Semantic disagreement is therefore often harder to diagnose than geometric inconsistency.
Neural Fields and Dynamic 3D Representations
Dense uniform grids are simple but carry the discretization with them: resolution is fixed, memory grows with the bounded volume, and smooth surfaces become staircases. Each of these costs bites in a different way. Fixed resolution means choosing, at map-building time, a level of detail that may be wrong for every downstream use; memory growing with the full volume means that the empty air in a large room costs as much as the furniture; and staircase artifacts mean that surface normals, which contact planners and physics engines need, are poorly defined at exactly the boundaries that matter. Sparse voxel, octree, and multiresolution grids alter these trade-offs by allocating storage selectively. A modern alternative is to represent the scene as a continuous function of coordinates, parameterized by a neural network.
From Grids to Coordinate Functions
A neural field is a learned mapping from spatial coordinates to scene quantities: occupancy probability, signed distance, density, color, or radiance. Querying it anywhere in continuous space evaluates the representation rather than indexing a fixed output voxel. This inverts the usual relationship between representation and query: a grid stores answers at grid points and interpolates between them, while a field computes the answer on demand. For a pure fixed-size coordinate MLP, parameter storage does not grow with the queried spatial volume, although resolution remains limited by model capacity. Hybrid neural fields can add multiresolution hash grids, sparse voxels, or explicit primitives whose storage does scale with coverage and detail. Gradients with respect to coordinates are available by automatic differentiation, which matters for optimization and analysis. The components are:
- Coordinate input: a position, optionally with viewing direction or time.
- Feature mapping: an encoding of coordinates (more on this below) that makes the target function learnable.
- Field network: a small MLP mapping encoded coordinates to scene quantities.
- Query-based supervision: the network is trained on observations tied to coordinates, such as "this ray terminates here" or "this pixel has this color."
The immediate question is why an MLP is a good idea at all, because vanilla coordinate networks have a well-documented weakness: ReLU MLPs are piecewise linear and often learn low-frequency structure before high-frequency detail, a phenomenon called spectral bias. Under a fixed model and optimization budget, that preference can blur the sharp boundaries that geometry depends on. A standard remedy is a Fourier feature mapping: before feeding coordinates to the network, map them through random frequencies,
with a matrix of random frequencies. The sinusoidal encoding exposes basis functions at selected spatial frequencies and changes the optimization bandwidth. The MLP can combine those features to fit fine detail instead of constructing all high-frequency variation from many raw-coordinate piecewise-linear regions. The frequency distribution in is a design parameter: too narrow a bandwidth loses detail, while an unnecessarily wide bandwidth can increase noise-fitting risk with finite samples and insufficient regularization. Bandwidth and regularization should be tuned against held-out data. Let's see the effect directly, by fitting a 2D occupancy field (a toy stand-in for a 3D neural field) with and without Fourier features.
import torch
import torch.nn as nn
torch.manual_seed(0)
n_grid, field_extent = 96, 1.0
def make_field(n, extent):
"""Signed distance of three disks on a 2D grid, and its occupancy."""
xs = np.linspace(-extent, extent, n)
X, Y = np.meshgrid(xs, xs)
pts = np.stack([X, Y], axis=-1).reshape(-1, 2)
d = np.stack(
[
np.linalg.norm(pts - np.array([-0.35, -0.20]), axis=1) - 0.28,
np.linalg.norm(pts - np.array([0.30, 0.30]), axis=1) - 0.18,
np.linalg.norm(pts - np.array([0.35, -0.35]), axis=1) - 0.12,
]
)
return pts, d.min(axis=0), (n, n)
pts, sdf, field_shape = make_field(n_grid, field_extent)
occ = (sdf < 0).astype(np.float32)
class CoordMLP(nn.Module):
def __init__(self, in_dim=2, width=64, depth=3):
super().__init__()
layers = [nn.Linear(in_dim, width), nn.ReLU()]
for _ in range(depth - 1):
layers += [nn.Linear(width, width), nn.ReLU()]
layers += [nn.Linear(width, 1)]
self.net = nn.Sequential(*layers)
def forward(self, x):
return self.net(x).squeeze(-1)
def fourier_features(x, B):
proj = 2 * np.pi * x @ B.T
return torch.cat([torch.cos(proj), torch.sin(proj)], dim=-1)
def train_field(encode, in_dim, steps=600, lr=1e-2, batch=2048):
model = CoordMLP(in_dim=in_dim)
opt = torch.optim.Adam(model.parameters(), lr=lr)
Xt = torch.tensor(pts, dtype=torch.float32)
yt = torch.tensor(occ, dtype=torch.float32)
for _ in range(steps):
idx = torch.randint(0, len(Xt), (batch,))
x, y = Xt[idx], yt[idx]
opt.zero_grad()
loss = nn.functional.binary_cross_entropy_with_logits(
model(encode(x)), y
)
loss.backward()
opt.step()
return model
B = torch.randn(16, 2) * 4.0
model_plain = train_field(lambda x: x, in_dim=2)
model_fourier = train_field(lambda x: fourier_features(x, B), in_dim=32)with torch.no_grad():
Xt = torch.tensor(pts, dtype=torch.float32)
pred_plain = torch.sigmoid(model_plain(Xt)).numpy().reshape(field_shape)
pred_fourier = (
torch.sigmoid(model_fourier(fourier_features(Xt, B)))
.numpy()
.reshape(field_shape)
)
occ_grid = occ.reshape(field_shape)
def iou(pred):
p, g = pred > 0.5, occ_grid > 0.5
return (p & g).sum() / (p | g).sum()
occupied_fraction = occ_grid.mean()
iou_plain = iou(pred_plain)
iou_fourier = iou(pred_fourier)Occupied fraction of the domain: 0.096 IoU, plain coordinate MLP: 0.972 IoU, Fourier-feature MLP: 1.000
In this seeded realization, both networks fit the rough shape, but the plain coordinate MLP blurs the boundaries while the Fourier-feature model produces sharper edges and higher intersection-over-union. The occupied fraction provides the context for why this matters: the disks occupy only a minority of the domain, so a network that predicts the smooth background well can achieve deceptively decent overall accuracy while being systematically wrong along every boundary, which is exactly where a planner needs the map to be right. This is an illustration, not an isolated causal estimate of the encoding effect. Hidden depth and width, training data, and step count are held fixed, but the Fourier mapping increases the input dimensionality and first-layer parameter count. Because the two training calls consume one advancing random-number stream, their parameter initializations and realized minibatch sequences also differ. A controlled comparison would use paired batch schedules and repeated seeds, then either match total capacity or explicitly treat the larger first layer as part of the intervention. The visible result is consistent with the spectral-bias motivation, but these panels alone do not establish which changed factor caused the difference.



Neural Radiance Fields and Their Descendants
One of the most influential neural-field formulations for view synthesis is the neural radiance field (NeRF). Here maps a 3D position and viewing direction to emitted color and volume density. The viewing-direction input is what allows the field to represent view-dependent appearance, such as specular highlights that move as the camera moves, while the position input carries the underlying geometry. A camera image is rendered by volume rendering: march a ray through the field, and accumulate color weighted by transmittance,
Here is the number of ordered ray intervals, is the color predicted at sample , and is the background color. Each is the conditional opacity, or termination probability at sample given that the ray reached that interval, and is the probability it survived all earlier intervals. Their product is the unconditional probability mass assigned to termination at sample . The residual survival mass weights the background color ; that term vanishes for a black background and becomes negligible when the sampled volume is effectively opaque. The formula is a soft, differentiable version of ray casting: instead of taking the first surface hit, it sums contributions from all samples along the ray, each discounted by the probability that the ray was already absorbed before reaching it. Samples deep behind an opaque surface contribute almost nothing because has decayed to nearly zero, which is how occlusion emerges from a fully differentiable sum. Because rendering is differentiable, the network trains directly from posed images by gradient descent on photometric reconstruction. A shared radiance field couples the training views through one differentiable rendering model. Standard NeRF assumes known camera poses and jointly optimizes density and appearance; later methods such as BARF additionally parameterize and refine camera poses. This shared rendering objective encourages cross-view consistency, but photometric ambiguity, calibration error, and optimization pathologies mean it does not guarantee unique or correct geometry.
Three practical lineages matter for world models:
- Fast per-scene fields: multiresolution hash encodings and sparse explicit structures can reduce per-scene optimization dramatically by shifting work toward local learned lookups. The achieved runtime depends on the method, hardware, scene, optimization budget, and target quality. These approaches replace much of a deep MLP's work with learned values on a multiresolution structure, so the network refines locally stored detail. Speed matters for world models because a representation that is too slow to update cannot participate in the online perception-prediction-action loop.
- Feed-forward generalization: rather than optimizing per scene, networks predict field parameters (or directly predict geometry) from one or a few images, amortizing a learned prior over scenes. This is the geometry-flavored cousin of the amortized inference we discussed in Part III. The optimization-based version finds the scene that best explains the images; the feed-forward version predicts a scene from learned priors in one pass, and some systems optionally refine that prediction with per-scene optimization. Feed-forward inference is faster but prior-dependent in the same broad sense as monocular depth.
- Explicit hybrid representations: 3D Gaussian splatting represents the scene as a set of anisotropic 3D Gaussians with positions, covariances, opacities, and colors, optimized through a differentiable rasterizer. It keeps the differentiable, multi-view-consistent training recipe of NeRF but replaces the implicit field with an explicit, sortable, splattable primitive set, which is what makes real-time rendering possible. The explicit form exposes direct per-primitive operations: primitives can be added, removed, moved, and grouped. Later systems can exploit those operations for editing or dynamics, but object-level use still requires correspondence, persistent identity, and grouping mechanisms.
From 3D to 4D
Real environments change. Extending neural fields to 4D means representing , and the interesting design question is how time enters, because different answers buy different structure. Three prominent families are useful for organizing the literature:
- Time-conditioned fields: add (or a time encoding) as network input. This simple parameter sharing can encourage smoothness, but it provides no explicit temporal-coherence guarantee and may generalize poorly beyond observed times. That limitation motivates structured deformation or motion models for world-modeling tasks.
- Canonical space plus deformation: model a static canonical scene and a learned warp that maps time- points into canonical space. Dynamics become a flow of geometry rather than an independent stack of frames, which regularizes the model and makes motion an explicit, queryable quantity, closely related to the scene flow of the previous section. The structural assumption is that most of the scene persists and only moves: appearance and shape live in the canonical field, and the warp carries the dynamics. When that persistence assumption fails, a single topology-preserving deformation of a fixed canonical field cannot represent births, deaths, or topology changes without additional time-dependent density, visibility, appearance, or residual mechanisms. More general non-injective warps or time-varying field support relax this limitation but also weaken the simple persistent-scene interpretation.
- Per-time explicit representations: sequences of Gaussian splats or meshes with motion fields between them form an active family in dynamic-scene and driving-scene reconstruction. This family gives up some of the compactness of a single global representation in exchange for per-frame flexibility, and the motion fields between frames reconnect the frames so that motion remains a first-class quantity rather than an artifact of frame-to-frame comparison.
It is tempting to call a 4D reconstruction "a world model of the scene." Resist that temptation, at least for now. A neural field is a scene representation. Paired with camera geometry, a renderer, and a likelihood, it can support the observation model from our Part I taxonomy. Because a 4D field includes time, it may encode or interpolate time-indexed changes in geometry and appearance. By itself, however, it does not define an action-conditioned state-transition model or establish reliable future extrapolation. Without actions and transition structure as inputs, it also cannot answer counterfactuals about actions the agent did not take, which are exactly the questions a planning agent must ask. Reconstructing yesterday and predicting tomorrow are different capabilities. The next chapter, on physical dynamics and constraints, is about that second half.
What Geometry Contributes to a World Model
Before closing, it is worth assembling the ledger. Geometry is not one technique but a set of distinct contributions to a world-modeling system, and being precise about which one you are using clarifies both design and evaluation. The same geometric machinery shows up in four different roles, and confusing the roles leads to characteristic mistakes: evaluating a sensor model as if it were a transition model, or expecting a state format to carry its own dynamics.
- Geometry as state: an allocentric map can describe scene geometry in a world frame that is invariant to egomotion, while camera-frame depth and egocentric occupancy change equivariantly under the known frame transform. Both forms can contribute to the control-sufficient state discussed in Part III, provided the coordinate frame is explicit. Moving the robot translates and rotates an egocentric map predictably rather than producing arbitrary view-dependent changes. This equivariance should not be confused with controllability in control theory, which asks whether admissible inputs can steer a system between states. Separating the persistent world-frame component from the known observation or frame transform lets a learned transition describe scene evolution without absorbing egomotion into the dynamics. The full agent-world state still includes the agent's evolving pose and action effects.
- Geometry as observation model: geometric state paired with sensor geometry and a neural-field, mesh, or splat renderer can make a parameterized observation prediction differentiable and serve as the forward model inside . Given a hypothesized state, you can render what the sensor should see and compare it with the observation. With a specified likelihood, prior, and parameterization, gradients through that discrepancy support approximate maximum-likelihood or MAP inference over state. Ambiguities, local minima, model mismatch, and the choice of loss still determine what the optimization recovers.
- Geometry as a training signal: multi-view consistency, reprojection error, and photometric reconstruction provide self-supervised objectives without semantic labels. Failure to render a consistent shifted view shows that the combined geometry-and-observation model is inadequate, although the cause may lie in geometry, appearance, visibility, calibration, renderer capacity, or optimization. Next-frame prediction and cross-view consistency can therefore come apart: a video predictor may capture appearance and motion well enough for one-step forecasts while remaining inconsistent across viewpoints. Under adequate parallax and valid image-formation assumptions, reprojection is a complementary test that is often especially diagnostic of cross-view structure. It is not a proof of unique or correct geometry.
- Geometry as a planning substrate: collision checking, reachability, visibility reasoning, and grasping all operate on geometric state. A prediction of "the chair will be at pose P in 3 seconds" gives a motion planner a direct spatial representation. The planner can query trajectory intersections, grasp reachability, and visibility through the representation and its spatial index, often without routing each decision through image synthesis and perception. Exact cost still depends on the representation, collision model, and planner architecture.
The recurring theme is the distinction we have drawn since Part I: open-loop prediction quality and closed-loop decision usefulness come apart. A photorealistic video prediction can score well while being geometrically inconsistent across views, making it unsuitable for metric path planning even though its usefulness for other decisions remains an empirical question. Conversely, a coarse occupancy forecast that is geometrically consistent may enable reliable navigation despite looking crude. Predictive fidelity, representation quality, uncertainty quality, and decision usefulness are different axes. Explicit geometry offers unusually direct control over them: sharper reconstruction for representation quality, occupancy probabilities and covariances that can be evaluated for calibration, differentiable rendering for predictive fidelity, and plan-compatible state for decision usefulness.
Limitations and Impact
The geometric toolkit comes with assumptions that fail in characteristic ways, and knowing the failure modes is part of the competence.
One of the most consequential assumptions in the methods discussed here is a static world. Occupancy grids accumulate evidence indefinitely, which is only sound if cells do not change. In dynamic environments, a naive static-world SLAM pipeline may discard moving points as outliers or, worse, bake them into the map as ghost geometry. Dynamic and hybrid systems instead detect, mask, track, or explicitly model moving objects. Ghost geometry is nastier than missing geometry when a planner trusts it and routes around objects that are no longer there. Dynamic-scene SLAM and 4D reconstruction address this, but they reintroduce the segmentation problem: separating egomotion, object motion, and deformation is impossible without committing to some structure, and the wrong commitment produces confident nonsense. If you assume two rigid bodies where the world has one deformable one, limited observations may let the estimator report two objects moving in a coordinated way. The explanations can be observationally ambiguous, although boundary discontinuities, correlated residual structure, additional views, and explicit model comparison may expose the mismatch. Relatedly, the independence assumptions that make grid filters tractable, cells independent and measurements independent given the map, are violated by correlated sensors and correlated errors. Real range sensors can have systematic calibration, timing, pose, or environmental biases that correlate many or all rays in a scan, and neighboring cells are physically part of the same surfaces. Drift is accumulated estimation error, especially pose error produced by sequential integration. Violated independence assumptions and correlated sensor biases can contribute to drift, but are not synonymous with it. A valid loop closure can constrain accumulated trajectory drift; it does not repair every local sensor, calibration, semantic, or model error.
Second, geometric fidelity is expensive and its value is task-dependent. Dense metric reconstruction of an entire environment at centimeter resolution is far more memory, compute, and calibration burden than many tasks need, while some tasks (manipulation under occlusion, liquid handling, deformable objects) need geometry richer than any of these representations provide. There is a real engineering judgment call in choosing the coarsest geometric state that is sufficient for the decisions at hand, echoing the state-abstraction arguments of Part III. Overshooting buys cost; undershooting buys plans that fail on contact. The judgment is made harder by the fact that sufficiency is not static: a navigation task may need only coarse occupancy today, but the same robot asked to open a drawer tomorrow needs contact-accurate geometry of the drawer's handle, so the choice of geometric state is a bet about the task distribution the agent will face.
Third, the semantic and geometric layers can disagree. Despite a substantial literature on joint fusion, conflicts remain unresolved in important regimes. A semantic map that classifies a cell as "floor" while geometry says it is a 30-centimeter step has a conflict that matters to a wheeled robot, and its resolution remains open: the classifier may be wrong, the geometry may be wrong, or the category "floor" may simply be too coarse for the decision at hand. Learned monocular components remain subject to geometric scale non-identifiability unless metric supervision or another prior supplies a scale anchor. A feed-forward 3D reconstruction without such an anchor can be unusable for metric navigation even when it looks plausible; learned metric priors can select a scale, but the pixels alone do not identify it. Plausible-looking reconstructions can hide severe metric errors, so visual inspection is not sufficient validation.
None of this diminishes the impact. Geometry provides a longstanding, widely used bridge between raw high-dimensional observations and compact, action-relevant state. It also supplies self-supervised objectives such as multi-view consistency and reprojection, and makes image-formation models explicit and differentiable so perception and prediction can be trained together. Modern learned systems reuse analogous structures: egomotion-aware latents parallel geometric state, cross-view losses use projection and correspondence constraints, and learned renderers build on differentiable image-formation models. Evaluation follows directly from the four roles: reprojection and novel-view consistency for the observation model, absolute trajectory error and relative pose error for localization, reconstruction IoU or depth accuracy for mapping, and, decisively, downstream task performance for whether the geometric state was sufficient. A model can be excellent on the first three and still fail the fourth if the geometry it chose to represent is not the geometry the task depends on.
Summary
- Projection destroys depth: a pinhole camera maps each visible 3D point to a pixel; conversely, each pixel back-projects to a ray, so a single image leaves an independent depth ambiguity along each ray. Calibrated rigid monocular multi-view reconstruction instead has a shared global-scale ambiguity. Multiple views, active sensing, or learned priors can supply depth information; a learned prior may predict metric scale without making it geometrically identifiable from the image alone.
- Rigid transforms and homogeneous coordinates are the bookkeeping that connects world, body, and sensor frames. A rigid camera-to-body mount transform is fixed calibration; composing it with the evolving body pose gives the world-to-camera transform, which changes as the agent moves. Intrinsics are often treated as fixed for a stable imaging configuration but must be updated when image formation changes. The homogeneous form turns transform composition and inversion into ordinary matrix operations, making frame trees manageable in practice.
- Depth, pose, and scene flow are coupled estimation problems. Decomposing scene flow into a rigid (egomotion or object) component plus a residual separates camera-induced change from real dynamics and can cue object segmentation. With correct, well-distributed matches and sufficiently independent unbiased errors, the rigid fit can also average noise across points.
- SLAM treats map and trajectory as one joint inference problem. EKF-SLAM makes the dense coupling explicit; sparse graph formulations and incremental solvers scale estimation, while loop closures add long-range constraints that can correct accumulated drift. Occupancy grids accumulate per-cell Bernoulli beliefs in log-odds form and explicitly represent unknown space, at the price of static-world and independence assumptions. Preserving unknown space enables uncertainty-aware objectives to drive exploration.
- Neural fields expose continuous coordinate functions, often replacing dense uniform output grids while sometimes using sparse or multiresolution grids internally. Fourier features can change the optimization bandwidth used to address spectral bias; NeRF-family methods and Gaussian splatting make the sensor model differentiable and encourage multi-view consistency; 4D extensions add time through deformation fields or time-conditioned parameters, with canonical-plus-warp providing a particularly structured neural-field treatment relative to direct time conditioning.
- Keep the roles distinct: a geometric reconstruction is a state format. Paired with an explicit sensor model or renderer, it supports an observation model. It is not, by itself, a transition model. A system that renders the past beautifully has not yet earned the right to be called a world model.
Geometry tells us what is where and can describe observed motion through scene flow or time-indexed 4D structure. Geometry alone does not specify the action-conditioned dynamics needed to predict counterfactual futures: whether the stacked boxes will topple after a push, how the ball will bounce under a changed action, or where disturbed water will flow. That is the domain of physical dynamics and constraints, and it is exactly where we go in the next chapter.
Quiz
Ready to test your understanding? Take this quick quiz to reinforce what you've learned about geometry, mapping, and 3D/4D state.
Geometry, Mapping, and 3D/4D State Quiz
Reference
Citation details
Cite or share this article.
Continue with the full handbook
This chapter is part of World Models Handbook. Use the handbook page to browse the complete table of contents and continue reading in sequence.
Explore World Models HandbookStay up to date
Get articles, book updates, and news delivered to your inbox.
No spam, unsubscribe anytime.
Join the community
Sign in to remove popups, track your reading progress, and join the discussion.

Comments
No comments yet. Be the first to share your thoughts!