Skip to main content

Run the DYNOS planner in the loop with an external vehicle simulator

Project description

dynos-sim-bridge

A worked example: run the DYNOS planner in the loop with an external vehicle simulator. This package is scaffolding: it ships a stub SimHardware plus a trivially simple StochasticSim that you replace with calls into your simulator, and the wiring (runnable.py, mission.py) that lets dynos connect find it.

It demonstrates the two channels a simulator needs, both on the one SimHardware class:

  • Motion out (planner -> simulator): SimHardware implements the goto transition by commanding your simulator, exactly like the real Sentry hardware class commands the vehicle.
  • State in (simulator -> planner): the vehicle's real position flows back through a servant belief -- a @Belief(fluent=at) callback the backend polls after each step, exactly the way it runs a local @Belief. Whatever waypoint the simulator reports becomes at(<waypoint>) in the planner's world. If the simulator ended up somewhere other than commanded, the belief reflects reality and the planner replans from there.

There is no separate position-sync step and no out-of-band set_belief: the planner always builds on the observed position because the observation is the channel.

Install

You will be modifying the source, so install editable:

pip install -e dynos-sim-bridge

This pulls in dynos-client and dynos-sentry-domain.

What's in this repository

bridge.py

Provides StochasticSim (the stand-in simulator) and SimHardware, which wires it to the planner:

  • @Action(transition=goto) go_to: command the simulator to drive to the leg's endpoint.
  • @Belief(fluent=at) observe_position: report the vehicle's real symbolic position back to the planner.

Everything above the Edit away down here line is plumbing you should leave alone; replace StochasticSim with a bridge to your real simulator (same goto/position shape).

mission.py

Provides build_sim_survey_mission(zone_name). Edit if you want a different sequence.

runnable.py

Provides SimBridgeNode, the dynos connect-compatible entry point. You probably don't need to edit this.

SimHardware claims the goto transition. Registering it replaces whatever was executing goto (e.g. the sentry-mock hardware's own goto) -- that is the point: your simulator becomes the motion executor. Run the bridge instead of a second motion provider, not alongside one.

Why a servant belief, not create_object + set_start

The tempting way to tell the planner where the vehicle is each tick is to create a current_location coordinate and reset the initial state. Don't:

  • set_start re-derives the whole initial state; it is a planning-time input, not a per-tick observation channel.
  • Two points at the same lon/lat and altitude are the same physical point, so a current_location that lands on a known waypoint is collapsed onto that waypoint by the backend, and you then have to discover the canonical name.

A servant belief skips all of that: the backend asks your servant "where is the vehicle at?" and your observe_position answers with the at fluent symbol over a waypoint the planner already knows.

How the round-trip works

  1. You launch the bridge as a servant: dynos connect dynos_sim_bridge.runnable:SimBridgeNode. Registering SimHardware advertises both the goto action and the at belief, then it idles.
  2. From a second process you set the goal and execute a mission. No position sync is needed first -- the planner learns the position from the belief.
  3. The planner expands full_coverage_of(zone) into goto legs and dispatches each to your servant.
  4. SimHardware.go_to drives the simulator toward the leg's endpoint x. Then the backend polls observe_position:
    • Vehicle is at x: the observation confirms the goto effect at(x); the planner continues to the next leg.
    • Vehicle ended up at y (current, obstacle, missed move): the observation reports at(y); the effect at(x) is not confirmed, so the step gates and the planner replans toward the same goal from y. This is the planner operating on updated symbolic knowledge -- the point of running it in the loop.
  5. The mission ends with full_abort (controlled ascent).

The servant belief goes through the client API: @Belief/BeliefResult are exported from dynos_client, so a remote servant running with dynos_client alone reports beliefs exactly as an in-tree robot class does with the backend-side @Belief.

Replacing the stub

Replace StochasticSim with a small adapter over your simulator, keeping the same two methods:

goto(target): command your simulator to drive to target (a waypoint name) and return whether it arrived.

position(): return the name of the waypoint the vehicle is currently on, or None when it is between waypoints (the belief then reports "unchecked" and the planner keeps its prior position).

Coordinates follow the project convention: (longitude, latitude), degrees for geographic, meters for local_enu. Altitude is part of a point's identity.

Test offline

Before pointing at the real backend, run the package's own tests:

pip install -e "dynos-sim-bridge/[dev]"
pytest dynos-sim-bridge/tests/ -v

These exercise StochasticSim, the goto plumbing, and the at belief. No network or session needed. The end-to-end loop (backend polls the belief and continues or replans) is covered by the sentry integration test tests/sentry/test_servant_beliefs.py.

Run it for real

Two terminals.

Terminal 1 is your simulator bridge:

dynos login  # logins persist across terminals but expire after an hour
dynos session create --robot sentry-mock
dynos connect dynos_sim_bridge.runnable:SimBridgeNode

Leave it running. It executes goto whenever the backend reaches a leg, and answers the at belief whenever the backend polls it.

Terminal 2 is the mission. Create the survey zone and run:

dynos call create zone.json
from dynos_client import RemoteOrchestrator
from dynos_sim_bridge.mission import build_sim_survey_mission

orch = RemoteOrchestrator.from_config(timeout_s=3600)
for r in orch.execute_blocks(build_sim_survey_mission("site_alpha")):
    print(r)

Public API

Symbol From Purpose
SimHardware dynos_sim_bridge.bridge The robot class you edit; executes goto, observes at.
StochasticSim dynos_sim_bridge.bridge The trivial stand-in simulator you replace.
SimBridgeNode dynos_sim_bridge.runnable The dynos connect entry point.
build_sim_survey_mission(zone) dynos_sim_bridge.mission Take over, survey, recover.

Troubleshooting

Bridge never gets an assignment: the mission hasn't reached a goto leg. Check dynos call state --scope public.

at(<name>) unresolved: the name your position() returned isn't a registered object. Return the name of a waypoint the planner knows (e.g. the leg's endpoint), not an ad-hoc string.

For cross-package issues (login, session, connection), see user_guide.md or dynos-client's README.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dynos_sim_bridge-0.1.5.tar.gz (10.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dynos_sim_bridge-0.1.5-py3-none-any.whl (8.6 kB view details)

Uploaded Python 3

File details

Details for the file dynos_sim_bridge-0.1.5.tar.gz.

File metadata

  • Download URL: dynos_sim_bridge-0.1.5.tar.gz
  • Upload date:
  • Size: 10.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.8.10

File hashes

Hashes for dynos_sim_bridge-0.1.5.tar.gz
Algorithm Hash digest
SHA256 37ce2a2f14b1d511510b9137b5438e3af207fb57a48b4b7d4bc2f5572214cf9d
MD5 44716262ca7e8caf6cb2fecc201d1d5d
BLAKE2b-256 32860babc1f3cd3309a3511f52cf7d22644c68e2d1fc15ee285b56043a889f0f

See more details on using hashes here.

File details

Details for the file dynos_sim_bridge-0.1.5-py3-none-any.whl.

File metadata

File hashes

Hashes for dynos_sim_bridge-0.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 42f3356f3dc071ba0d144e7df505d0da0475d595df00518267e53c6cbb2396fb
MD5 b11f7f5e33676dfd5f249ade4c72e4e8
BLAKE2b-256 55fcf93003937178c3bd606ab73415cfe260e22c36ea4230a5c225d9ccc68cf8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page