The cortical messaging protocol: one payload for observed states, hypothesized states and goals.
Mirrors tbp/monty/cmp.py. Everything that crosses a module boundary in
Monty is a Monty.Cmp.Message (or a Monty.Cmp.Goal), which is what makes
arbitrary module configurations — sm_to_lm_matrix, lm_to_lm_matrix,
lm_to_lm_vote_matrix — expressible as wiring rather than code.
Two representations live here:
- the structs (
Message,Goal,AttentionRegion), used in the runtime; - the wire form, plain maps with string keys, used for persistence, the step inspector in the UI, and the simulator sidecar.
The wire form is deliberately close to Monty's own ActionJSONEncoder /
message dictionaries so a Python fixture can be compared field by field.
Summary
Types
@type message() :: Monty.Cmp.Message.t() | Monty.Cmp.Goal.t() | Monty.Cmp.AttentionRegion.t()
Anything that can travel on the CMP.
Functions
Reads a payload produced by encode/1 back into a struct.
Validation is the same as construction: a payload that would not have been
accepted by Message.new/1 is rejected here too.
The wire form of a CMP payload.
Pose vectors keep their type: a SurfacePoseVectors and an
OrientationMatrix are both 3×3, and confusing them rotates a reference
frame by 90 degrees without any number looking wrong.
@spec location_mean([Monty.Cmp.Message.t() | Monty.Cmp.Goal.t()]) :: [float()] | nil
Mean of the messages' locations, or nil when no message has a location.
Mirrors cmp.location_mean: a missing location is not zero, and the mean of
an empty list is not a point.