Puts the agent in front of the object before an episode's first step.
Mirrors the positioning half of ExperimentEnvironment.pre_episode in
tbp/monty/experiment/environment.py: for each configured procedure, build it
for the episode's target object, ask the world what is visible, and keep
stepping the world with the actions the procedure answers until it is finished.
Only the last procedure's verdict is kept — Monty's rule, because the
procedures are a pipeline (walk towards the object, then aim at it), not
alternatives.
Pure, like the rest of the port
Monty's loop mutates the environment and the procedure as it goes. Here the
world is threaded through explicitly — observe.(world, actions) answers the
observation, the agent's pose and the next world — and so is the procedure,
so a caller can watch the whole prologue happen without a process.
What a failed positioning means
Monty raises when a single-object scene never gets the centre pixel onto the target: the episode was set up wrong, and a run that starts anyway measures nothing. This answers an error, so a job can report it rather than crash a supervisor.
The step limit is the port's
Monty's loop has no bound, and a procedure that never finishes hangs the
experiment. This one stops after :max_steps — Monty's own procedures finish in
a few dozen steps — and says so. The bound only fires where Monty would hang.
Summary
Types
A world and actions in; the observation, the agent's pose and the next world out.
What positioning did: whether the last procedure ended in a good view, and how many steps it took.
Functions
Steps world until every procedure has finished.
Types
@type observe() :: (term(), [Monty.Frameworks.Actions.Action.t()] -> {map(), map(), term()})
A world and actions in; the observation, the agent's pose and the next world out.
@type outcome() :: %{ steps: non_neg_integer() | nil, success: boolean(), procedures: [String.t() | atom()] }
What positioning did: whether the last procedure ended in a good view, and how many steps it took.
steps is nil when the world positioned the episode itself and did not
report how much it moved — a world that ran Monty's pre_episode did the work,
and inventing a number for it here would be worse than saying nothing.
Functions
@spec prepare( [Monty.Frameworks.Environments.PositioningProcedures.GetGoodViewFactory.t()], integer(), term(), observe(), keyword() ) :: {:ok, term(), outcome()} | {:error, term()}
Steps world until every procedure has finished.
Options:
:distractors— how many other objects the scene has. A single-object scene the procedure never reaches the target in is an error; a cluttered one only needs the procedure to give up.:max_steps— the bound described in the moduledoc.
No procedures is Monty's "positioning is not configured": the world comes back untouched and nothing is stepped.