dynos-adaptive-resampling
A worked example: chain an ML-driven resampling step onto a Sentry survey. This
package is scaffolding: it ships a stub AdaptiveResampler that you
replace with your model, plus the wiring (runnable.py, mission.py) that
lets dynos connect find it and that lets the planner sequence "survey,
resample, resurvey".
The package contributes one new transition (resample_zone) and one new
mission template (build_resample_mission). Everything else is for you to
edit.
Install
You will be modifying the source, so install editable:
pip install -e dynos-adaptive-resampling
This pulls in dynos-client, dynos-sentry-domain, and numpy.
What's in this repository
domain.py
Declares resample_zone (transition), ResampleZoneParams (its parameter
dataclass), resampling_complete (a fluent the transition adds). Edit if
you need new fluents or parameters.
resampler.py
Provides the AdaptiveResampler class with @Action(transition=resample_zone).
Edit _gather_historic_data and _predict_new_zone (or whatever else you
need) to get your model integrated.
mission.py
build_resample_mission(zone) returns a Mission that does survey, resample,
resurvey. Pass the Zone object (e.g. Zone(name="site_alpha")), not its name
string. Edit if you want a different sequence.
runnable.py
Provides AdaptiveResamplingNode, the dynos connect-compatible entry point.
You probably don't need to edit this. Connecting it also registers this
package's domain module with the backend (so resample_zone becomes plannable
and dispatches back to your node) -- no edits to the backend or the Sentry
domain. The backend must have this package installed; for the local
demo below that is the same machine.
How the round-trip works
- You launch the resampler as a servant:
dynos connect dynos_adaptive_resampling.runnable:AdaptiveResamplingNode. The servant registers its transition + domain with the backend, then idles, polling for assignments. - From a second terminal you build the mission and call
execute_blocks. The first plan block surveys the source zone end-to-end. - The planner reaches
resample_zone(source_zone=site_alpha). It dispatches the assignment over HTTP to your servant. - Your
AdaptiveResamplerruns_gather_historic_data, then_predict_new_zone, and creates the newZoneon the backend (resampled_site_alpha) so the follow-up survey can plan coverage over it. - Once the new zone exists, the next plan block surveys it.
The vehicle-lifecycle bookends -- takeover, descent, and abort/recovery -- are inserted by the planner and the on-vehicle safety system. The mission you author is just the three survey/resample/resurvey blocks; you never hand-write a takeover or an abort.
Replacing the stub
You will edit resampler.py. Two methods shape the proposal:
_gather_historic_data(zone_name): return whatever your model needs. The
shipped stub returns a few synthetic sensor readings ({"longitude", "latitude", "value"}); you replace it with calls to a shared database, ROS
bag, the backend API (orch.list_objects(type_filter="zone")), an offline
NetCDF, etc.
_predict_new_zone(historic_data, new_zone_name, coverage_width, robot_width):
return a ready-to-create Zone (the domain object) -- not a side-car type. The
shipped stub is a trivial heuristic (it centers a 100 m x 100 m box on the
highest-value reading); replace it with your model:
from dynos_sentry.sentry import Zone
def _predict_new_zone(self, historic_data, new_zone_name, coverage_width, robot_width):
features = self._extract_features(historic_data["sonar_readings"])
prediction = self._model.predict(features)
return Zone(
name=new_zone_name,
vertices=self._prediction_to_polygon(prediction), # (lon, lat) corners
altitude=70.0,
speed=0.8,
coordinate_frame="geographic",
coverage_width=coverage_width, # sensor swath; keep > 0 or coverage can't plan
robot_width=robot_width,
)
do_resample then calls create_object(new_zone) for you. It gets a backend
handle from RemoteOrchestrator.from_config() (the config dynos connect
wrote); it also reads the source zone's coverage_width/robot_width and
threads them in so the resurvey flies the same sensor swath (falling back to
sane defaults if the source can't be read).
You can add fields to ResampleZoneParams (e.g. a confidence threshold), but
don't change the Zone parameter: the backend's coverage planner reads
Zone.vertices, Zone.coverage_width, etc. to draw tracklines, and it expects
the public schema.
Test offline
Before pointing at the real backend, run the package's own tests:
pip install -e "dynos-adaptive-resampling/[dev]"
pytest dynos-adaptive-resampling/tests/ -v
These exercise _gather_historic_data, _predict_new_zone, and do_resample
(with a fake backend that records the created zone). No network or session
needed.
Run it for real
Two terminals.
Terminal 1 is your resampler. This can be your laptop, a lab server, or the
same machine as the backend; the backend dispatches each assignment to
whichever servant is currently registered for resample_zone.
dynos login # logins persist across terminals but expire after an hour
dynos session create --robot sentry-mock # Omitting '--robot sentry-mock' is valid but will omit important robot knowledge like coordinates, which is probably not what you want
dynos connect dynos_adaptive_resampling.runnable:AdaptiveResamplingNode
Leave it running. It executes resample_zone whenever the backend reaches that
step.
Terminal 2 is the mission. Create the source zone and run the adaptive mission:
dynos call create zone.json
from dynos_client import RemoteOrchestrator
from dynos_sentry.sentry import Zone
from dynos_adaptive_resampling.mission import build_resample_mission
orch = RemoteOrchestrator.from_config(timeout_s=3600)
results = orch.execute_blocks(build_resample_mission(Zone(name="site_alpha")))
for r in results:
print(r)
While it runs, monitor from a third terminal:
dynos call state --scope public # current symbolic state, pruned only for the symbols you're expecting
dynos call goal # current goal
dynos call objects --type zone # source + resampled zones
What the mission does, step by step
The mission you author is three blocks; the planner and the on-vehicle safety system add the lifecycle steps around them.
- Survey the source zone (
full_coverage_of(site_alpha)). The planner prefixes the takeover and descent it needs. - Resample. The plan dispatches
resample_zone(source_zone=site_alpha)to your servant; your model createsresampled_site_alphaon the backend. - Resurvey (
full_coverage_of(resampled_site_alpha)).
Recovery (full_abort, controlled ascent) is owned by the on-vehicle safety
system, not authored in the mission.
Public API
| Symbol | From | Purpose |
|---|---|---|
resample_zone |
dynos_adaptive_resampling.domain |
The transition that fires your @Action. |
ResampleZoneParams |
dynos_adaptive_resampling.domain |
Its parameter dataclass (source_zone: Zone). |
resampling_complete |
dynos_adaptive_resampling.domain |
Fluent the transition adds. |
AdaptiveResampler |
dynos_adaptive_resampling.resampler |
The class you edit. |
AdaptiveResamplingNode |
dynos_adaptive_resampling.runnable |
The dynos connect entry point. |
build_resample_mission(zone) |
dynos_adaptive_resampling.mission |
Survey, resample, resurvey. |
Troubleshooting
Resampler never gets an assignment: The mission hasn't reached resample_zone
yet. Check dynos call state --scope public.
No plan found: The source zone doesn't exist, has no vertices, or has
coverage_width <= 0. Check dynos call objects --type zone.
Resurvey failed: the resampled_* zone is missing fields. It needs vertices
(3+), coverage_width > 0, robot_width > 0, and coordinate_frame. The
shipped _predict_new_zone sets all of these; if you replaced it, make sure
your Zone still carries them.
For cross-package issues (login, session, connection), see user_guide.md or
dynos-client's README.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dynos_adaptive_resampling-0.2.2.tar.gz.
File metadata
- Download URL: dynos_adaptive_resampling-0.2.2.tar.gz
- Upload date:
- Size: 13.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.8.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fa75d116d0614852831a5274ddee627fbc424e1606a14d13d9313f66749238e9
|
|
| MD5 |
d0cff54092613c57e006914298e14016
|
|
| BLAKE2b-256 |
fed14c07a12b773f928b4feef5bf5f59c4de7b2e12e5057c62c2a2d90b1903a2
|
File details
Details for the file dynos_adaptive_resampling-0.2.2-py3-none-any.whl.
File metadata
- Download URL: dynos_adaptive_resampling-0.2.2-py3-none-any.whl
- Upload date:
- Size: 11.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.8.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7c52d935966373975149fea99dc24da6ca6fd21d11783402e31747d0957c72b2
|
|
| MD5 |
70c8ce127c5e5fbe2559aa521ac8d831
|
|
| BLAKE2b-256 |
4d45e326a316c840544f74d2d1f177b9b93cdee532958409aa20526156b8a218
|