Skip to content

Add MightyCamera native pose support for path following - #1252

Draft
zlite wants to merge 3 commits into
mainfrom
zlite/mighty-camera-gps
Draft

zlite wants to merge 3 commits into
mainfrom
zlite/mighty-camera-gps

Conversation

@zlite

@zlite zlite commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

MightyCamera can supply local position and heading directly to the path_follow template, using the same native pose abstraction as T265 and odometry.

Following Ezward's review suggestion, the integration is split into two parts:

  • MightyPose subscribes to the SDK's public body-pose stream and outputs the raw pose dictionary, freshness, and timing metadata. It handles timestamp ordering, tracking state, resets and connection age.
  • MightyPoseTransform converts that raw pose into pos/x and pos/y in local metres, pos/angle in radians, and validity. It applies configurable map yaw and vehicle-forward orientation.

The synthetic NMEA/UTM bridge and geographic anchor settings have been removed. HAVE_MIGHTY is independent of HAVE_GPS. When both are enabled, Mighty supplies the driving pose while serial GPS measurements and optional GPS/IMU fusion remain in separate GPS outputs. No GPS/Mighty fusion or automatic fallback between coordinate frames is implied.

The change also includes optional finite-route look-ahead steering, bounded forward progress, corner throttle reduction, endpoint stopping, and latched path-error/behind-target stops. Existing closed-route PID defaults remain available. Invalid Mighty poses inhibit waypoint recording and zero output in both full-auto and assisted-steering modes; manual control remains available. Late/duplicate/timestamp-less poses do not replace a current estimate or refresh its age.

Setup and migration instructions are in docs/mighty.md. Configuration now uses HAVE_MIGHTY, MIGHTY_URL, MIGHTY_START_VIO, MIGHTY_MAX_AGE and MIGHTY_YAW_DEGREES. The obsolete GPS_SOURCE='mighty' selector fails before hardware construction with migration guidance. Optional high-rate predicted poses and bounded asynchronous diagnostic logs are included. The separately installed Mighty SDK HTTP read-to-read1 buffering patch used in local trials is documented, but is not installed by this PR.

Validation: 29 hardware-free unittest tests passed under Python 3.11 / Donkeycar 5.2; all changed Python files compile. Coverage includes native coordinates/quaternion heading, freshness and invalid data, pose ordering/reset, validity gates, look-ahead steering and stop/rearm, plus real template construction with hardware helpers mocked for Mighty alone, GPS alone, simultaneous GPS/Mighty, and GPS/IMU fusion coexistence. No hardware driving was started.

This remains a draft pending upstream CI and live validation of the direct-pose implementation. Earlier local trials of the controller and ordering fixes improved tracking but still showed occasional departures and origin/heading mismatches. Translation-health statistics are logged without an additional observability stop policy. VIO map persistence is not provided; replay requires matching physical origin and heading after VIO restarts.

@Ezward Ezward left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this could be a lot simpler if we just output pose directly. The path follow turns NMEA into pos/x, pos/y, pos/angle so I understand why this outputs NMEA, but it would be much simpler if it just output pose. So the pose is what is 'native' to the template. The T265 part does this very simply;

V.add(PosStream(), inputs=['rs/pos'], outputs=['pos/x', 'pos/y'])
and I would guess we could so something similar with the Mighty; https://mightycamera.com/docs/sdk/recipes#subscribe-to-pose

See this example (not working) on how this might work: https://share.google/aimode/mBVjiWAHdUl1aqF3Y

Comment thread donkeycar/parts/mighty_gps.py Outdated
lat, ns = coordinate(latitude, True)
lon, ew = coordinate(longitude, False)
# Speed/course are unknown; do not claim a measured speed of zero.
body = f"GPRMC,{now:%H%M%S}.{now.microsecond // 10000:02d},{'A' if valid else 'V'},{lat},{ns},{lon},{ew},,,{now:%d%m%y},,,"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like the camera could output a kind of standard pose; x, y, angle. The path follow template can use these directly and then there is not need to translate to NMEA and back. See how we do it for T265, which is pretty simple.

V.add(PosStream(), inputs=['rs/pos'], outputs=['pos/x', 'pos/y'])
Also, then we could use the Mighty and GPS together outside.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Ezward,
Excellent points and I thought the same thing since the gps.py part has to convert NMEA sentences into x, y, and angle.
The gps.py part could be modified to convert the NMEA sentences into x, y, and angle or not to do the conversion depending on whether the input is NMEA sentences from a GPS module or a the input is SLAM coordinates from the Mighty Camera?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Ezward, Excellent points and I thought the same thing since the gps.py part has to convert NMEA sentences into x, y, and angle. The gps.py part could be modified to convert the NMEA sentences into x, y, and angle or not to do the conversion depending on whether the input is NMEA sentences from a GPS module or a the input is SLAM coordinates from the Mighty Camera?

Not exactly. I'm saying it has nothing to do with GPS. The Path follow template has 'pose' (pos/x, pos/y, pos/angle) as it's primary abstraction. GPS is one way to get pose. Wheel encoders + Kinematics is another way. The Intel T265 was another way. So the Mighty Camera is just another way to get pose and it is more like the T265 than GPS. So I am suggesting a part the outputs the raw pose information from the camera and a second part the transforms it into our pose (pos/x, pos/y, pos/angle).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DocGarbanzo DocGarbanzo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@TCIII

TCIII commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

@DocGarbanzo,

Dirk, I think that we need to consider Ed's suggestions before we approve Chris's PR as Ed has made some good, relevant comments concerning the NMEA conversion requirements.

TCIII

zlite added 2 commits November 8, 2026 19:55
…pose diagnostics

Port local driving improvements with optional controller configuration, endpoint and path-error stops, timestamp regression rejection, high-rate pose requests and timing logs. Add heading, steering and ordering regression coverage and document SDK transport patch and remaining live-driving limitations.
Split raw SDK acquisition from the planar pose transform, publishing local metres and radians directly to the path-follow template. Make Mighty independent of serial GPS while keeping GPS measurements and optional GPS/IMU fusion in separate outputs. Preserve ordering, freshness and autonomous validity gates, document configuration migration, and cover source wiring with hardware-free integration tests.
@zlite zlite changed the title Add MightyCamera VIO GPS source for indoor path following Add MightyCamera native pose support for path following Nov 9, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants