Monty.Cmp.Message (ExTbpMonty.Core v0.1.0)

Copy Markdown View Source

A message in Monty's cortical messaging protocol (CMP).

Mirrors tbp/monty/cmp.py::Message. The same payload represents an observed state (from a sensor module), a hypothesized state (from a learning module) or a goal (from a goal generator) — the receiver decides how to read it.

Differences from the Python class, on purpose:

  • sender_type is an atom (:sm | :lm) here and the strings "SM"/"LM" on the wire (Monty.Cmp.encode/1), so a typo is a compile-time warning rather than a runtime assertion.

  • Construction returns {:ok, message} | {:error, reason} instead of raising, because messages are built inside supervised processes whose job is to keep the run alive.

  • Vectors are plain lists ([x, y, z], [[x, y, z], ...]), the shape Nx and JSON both read without conversion.
  • semantic_id is a field here and a private attribute in Python (percept._semantic_id). Monty sets it "just for logging" — its own words, on the line that sets it — and nothing in matching reads it; here a private field does not exist, so the annotation is a field and the promise is the same one Monty makes in a comment.

Summary

Types

Where a message came from. :gsg only appears on Monty.Cmp.Goal.

t()

Functions

The two principal curvature directions, for SurfacePoseVectors.

Looks a feature up among the morphological and then the non-morphological features.

True when the message was produced by a sensor module.

Builds a message, validating the fields the Python class asserts on.

Whether the sender believes the sensor is on an object.

Records how the sensor moved since the previous message, and optionally the point-pair feature that goes with it.

The surface normal, for messages carrying SurfacePoseVectors.

Applies a translation and/or rotation to the message's pose.

Types

pose_vectors()

sender_type()

@type sender_type() :: :sm | :lm | :gsg

Where a message came from. :gsg only appears on Monty.Cmp.Goal.

t()

@type t() :: %Monty.Cmp.Message{
  confidence: float(),
  displacement: %{optional(String.t()) => term()} | nil,
  location: vector() | nil,
  morphological_features: %{optional(String.t()) => term()},
  non_morphological_features: %{optional(String.t()) => term()},
  pass_message: boolean(),
  process_features_in_lm: boolean(),
  semantic_id: integer() | nil,
  sender_id: String.t(),
  sender_type: sender_type()
}

vector()

@type vector() :: [float()]

Functions

curvature_directions(message)

@spec curvature_directions(t()) ::
  {:ok, {vector(), vector()}} | {:error, :no_surface_pose_vectors}

The two principal curvature directions, for SurfacePoseVectors.

feature(message, name)

@spec feature(t(), String.t()) ::
  {:ok, term()} | {:error, {:feature_not_found, String.t()}}

Looks a feature up among the morphological and then the non-morphological features.

from_sensor_module?(message)

@spec from_sensor_module?(t()) :: boolean()

True when the message was produced by a sensor module.

new(attrs)

@spec new(map() | keyword()) :: {:ok, t()} | {:error, term()}

Builds a message, validating the fields the Python class asserts on.

A location-only message (process_features_in_lm: false) may omit the pose features; it only synchronises the receiver's sense of where the sensor is.

on_object?(message)

@spec on_object?(t()) :: boolean()

Whether the sender believes the sensor is on an object.

Monty's default is true when the feature is absent, because a message that says nothing about it came from a sensor that could not tell. The feature itself is a number — a sensor module writes 1.0 or 0.0, a goal generator 1 — which Monty's get_on_object hands on and every caller only ever asks as a question, so the answer here is the question's answer.

set_displacement(message, displacement, ppf \\ nil)

@spec set_displacement(t(), vector(), term() | nil) :: t()

Records how the sensor moved since the previous message, and optionally the point-pair feature that goes with it.

surface_normal(message)

@spec surface_normal(t()) :: {:ok, vector()} | {:error, :no_surface_pose_vectors}

The surface normal, for messages carrying SurfacePoseVectors.

transform_morphological_features(message, translation, rotation)

@spec transform_morphological_features(t(), vector() | nil, [[float()]] | nil) ::
  {:ok, t()} | {:error, :gaze_direction_not_transformable}

Applies a translation and/or rotation to the message's pose.

Mirrors Message.transform_morphological_features: the location moves by the translation, and the pose vectors are rotated by rotation * pose_vectors. A GazeDirection cannot be rotated — it is a goal direction, not a frame.