Monty.Frameworks.Models.MotorPolicies.SurfacePolicyCurvatureInformed (ExTbpMonty.Core v0.1.0)

Copy Markdown View Source

A surface policy that follows the principal curvature directions when it can.

Mirrors tbp/monty/frameworks/models/motor_policies.py::SurfacePolicyCurvatureInformed. SurfacePolicy walks the surface in a direction that is mostly the last one; this policy does that only when the surface tells it nothing, and otherwise heads along the object's own lines — the rim of a cup, the handle of a mug — by following a principal curvature direction.

Which line it follows, and for how long

It starts on the smallest principal curvature (in absolute value) and follows it for max_pc_bias_steps, then the largest, then back, alternating while the directions stay defined. When they stop being defined it falls back to the standard momentum step, and it will not consider curvature again until it has taken min_general_steps of those.

Two reasons to ignore a curvature direction

A direction that points mostly along the agent's z axis is ignored: on the rim of a cup the curvature direction comes out pointing away from the surface, which is an artefact of the agent re-orienting against a noisy estimate. And a direction that would take the sensor where it has already been is turned away from it by a search over headings — the first attempt flips a curvature direction that has just started, later ones rotate the heading at random, the search looks less strictly as it fails, and if nothing is free after a hundred attempts the original heading is kept.

What it shares with SurfacePolicy

In Monty this is a subclass and overrides __call__ (to record where a tangential step came from), tangential_direction and reset. Here it is a second struct carrying the same fields, calling SurfacePolicy.surface_step/6 and overriding the one method, which that step asks of the policy's own module (docs/monty-differences.md §2.9).

Summary

Functions

One step, with the place a tangential move came from remembered first.

A curvature-following surface policy.

Starts the next episode: the surface's own state goes with it.

Nothing beyond what a surface policy reports.

The direction of a tangential move: along a curvature line, or by momentum.

Types

t()

@type t() :: %Monty.Frameworks.Models.MotorPolicies.SurfacePolicyCurvatureInformed{
  action_sampler: Monty.Frameworks.Actions.ActionSamplers.ActionSampler.t(),
  agent_id: atom() | String.t(),
  alpha: float(),
  attempting_to_find_object: boolean(),
  continuous_pc_steps: non_neg_integer(),
  desired_object_distance: float(),
  following_heading_counter: non_neg_integer(),
  following_pc_counter: non_neg_integer(),
  ignoring_pc_counter: non_neg_integer(),
  is_jumping: boolean(),
  is_undoing_jump: boolean(),
  last_surface_policy_action: Monty.Frameworks.Actions.Action.t() | nil,
  max_pc_bias_steps: pos_integer(),
  min_dir_pref: boolean(),
  min_general_steps: non_neg_integer(),
  min_heading_steps: non_neg_integer(),
  pc_alpha: float(),
  pc_is_z_defined: boolean(),
  pre_jump_state: Monty.Frameworks.Models.MotorSystemState.AgentState.t() | nil,
  prev_angle: float() | nil,
  rng: :rand.state() | nil,
  setting_new_heading: boolean(),
  tangent_locs: [Monty.Geometry.Rotation.vector()],
  tangent_norms: [Monty.Geometry.Rotation.vector() | nil],
  tangential_angle: float() | nil,
  tangential_vec: Monty.Geometry.Rotation.vector() | nil,
  telemetry:
    Monty.Frameworks.Models.MotorPolicies.SurfacePolicyTelemetry.t() | nil,
  touch_search_amount: float(),
  undo_action: Monty.Frameworks.Actions.Action.t() | nil,
  undo_jump_actions: [Monty.Frameworks.Actions.Action.t()],
  use_goal_driven_actions: boolean(),
  using_pc_guide: boolean()
}

Functions

call(policy, ctx, observations, state, percept, goal)

One step, with the place a tangential move came from remembered first.

Monty records the sensor's location and surface normal whenever the previous action was the vertical orienting, because the tangential step follows it immediately: those are the places the sensor has walked to, as opposed to the corrective movements that put it there.

new(options)

@spec new(keyword()) :: t()

A curvature-following surface policy.

:alpha weights a standard step towards the previous one, :pc_alpha the same for the moving average of a curvature direction. :max_pc_bias_steps, :min_general_steps and :min_heading_steps are Monty's three counters, and they are required because their right values are a property of the experiment.

reset(policy)

@spec reset(t()) :: t()

Starts the next episode: the surface's own state goes with it.

state_dict(surface_policy_curvature_informed)

@spec state_dict(t()) :: map()

Nothing beyond what a surface policy reports.

tangential_direction(policy, ctx, state, percept)

@spec tangential_direction(t(), Monty.Context.t(), map(), Monty.Cmp.Message.t() | nil) ::
  {Monty.Geometry.Rotation.vector(), t()}

The direction of a tangential move: along a curvature line, or by momentum.

Monty's override of SurfacePolicy.tangential_direction. Curvature is only considered when the pose is fully defined and enough standard steps have been taken since the last time curvature was followed.