Display Popup icon Display Popup Full-screen popup display for ARC: show custom text with configurable timeout, font, text/background color, size and position via controlCommand(). Try it →
South Africa
Asked

ESP32-CAM NMS Pose Yaw Flips

I’ve got an ESP32-CAM (AI Thinker) flashed with the Synthiam ESP32-CAM firmware (set to Client Wi-Fi) mounted overhead and feeding ARC through the Camera Device skill as an EZ-B camera; it’s about 2.2 m above the floor with a slight 10-15 tilt, resolution set to 640x480 in Camera Device, and a small differential-drive bot with a printed glyph (about 120 mm) on top that I want to localize with the Camera NMS Pose skill and then hand off to The Better Navigator for waypoints. The stream looks clean and detection is solid in the center, but I’m seeing two issues: 1) the reported heading occasionally snaps 180 when the robot nears the left or right edge of the frame or rotates slowly in place, and 2) X/Y drifts ~10-20 cm toward the edges even after I set the origin and offsets in the Camera NMS Pose config. I’ve tried: rotating the image 180 in Camera Device, toggling horizontal/vertical flip to align the axes with my map, different resolutions (320x240 and 800x600), moving the camera closer to square-on (less tilt), bright uniform lighting, and a higher-contrast glyph print; I also tested lowering frame rate to reduce JPEG compression artifacts from the ESP32-CAM, but the yaw flip still appears intermittently. Before I redesign the mount again, what Camera Device and Camera NMS Pose configuration sequence do you recommend for an ESP32-CAM used as an overhead tracker to keep orientation continuous (avoid 180 snaps) and stabilize X/Y across the frame-specifically, should axis alignment be handled by rotate/flip in Camera Device or inside NMS Pose, and is there a heading smoothing/lock option I’m missing?



Related Hardware (view all EZB hardware)
ESP32 Cam by Espressif
ESP32-CAM as an EZB for Synthiam ARC: stream video, control GPIO/servos, AP/Client WiFi, and ARC D0-D23 to GPIO pin mapping.
Wi-Fi
Servos Varies
Camera
Audio
UART Varies
I2C
ADC Varies
Digital Varies

Related Robot Skills (view all robot skills)
Camera NMS Pose by Synthiam Inc.
Overhead camera tracks a glyph to give precise robot pose to ARC's NMS for multi-camera indoor/outdoor navigation and waypoint control
Robot Skill To Camera by Synthiam Inc.
Capture a robot skill's display and stream selected area as video to a configured camera device with FPS and live preview crop.

ARC Pro

Upgrade to ARC Pro

Experience the transformation – subscribe to Synthiam ARC Pro and watch your robot evolve into a marvel of innovation and intelligence.

Author Avatar
PRO
Canada
Twitter YouTube GitHub
#1  

What you’re describing is usually a combination of camera geometry + glyph edge detection + coordinate mapping, not just a bad setting.

For an ESP32-CAM overhead pose tracker, I’d recommend this tuning order in ARC:

1) Keep the camera feed "physically correct" first

In Camera Device, only use rotate/flip to make the image look like the robot/map orientation you want for humans.

  • If the camera is mounted upside down, rotate it there.
  • If the image is mirrored by the lens/mount, flip it there.
  • Try to avoid "fixing" tracking math with image transforms later in the pipeline.

In general:

  • Camera Device = image orientation
  • Camera NMS Pose = tracking calibration / area mapping

So yes, axis alignment should usually be handled in Camera Device, while NMS Pose should be reserved for scaling, offsets, and area setup.


2) Rebuild the NMS Pose calibration from a "neutral" mount

Those 10-20 cm edge drifts often happen when the camera is not close enough to square-on.

A 10-15 tilt at 2.2 m can absolutely introduce:

  • perspective distortion
  • heading bias near edges
  • X/Y nonlinearity

If possible, try to get the camera:

  • as perpendicular to the floor as possible
  • centered over the workspace
  • with the glyph staying well inside the middle 60-70% of the frame

If you must keep the slight tilt, expect some edge error. The system will always be most accurate near the center.


3) Use the largest practical glyph

A 120 mm glyph is okay, but for 2.2 m height and ESP32-CAM compression, a slightly larger glyph often improves stability.

If your bot can fit it, try:

  • 150-200 mm glyph

Bigger glyphs help with:

  • fewer pose ambiguities
  • less yaw flipping
  • better edge tolerance
  • more stable detection under motion blur/JPEG artifacts

About the 180 heading snaps

That symptom usually means the tracker is briefly losing confidence in the glyph orientation and then re-acquiring it in the opposite direction.

Common causes:

  • glyph too small in the frame
  • perspective distortion near image edges
  • motion blur while rotating slowly
  • compression artifacts from ESP32-CAM
  • the glyph pattern being seen in a "symmetrical-looking" way at low detail

Things that help:

  • keep the robot more centered in the frame
  • increase glyph size
  • reduce camera tilt
  • increase lighting
  • avoid very slow in-place rotation if the camera frame rate is low
  • use the highest stable resolution your ESP32-CAM stream can maintain without dropping frames

Is there heading smoothing / lock?

There isn’t typically a "heading lock" option in Camera NMS Pose itself that prevents that snap in the way you’re describing.

What you can do instead is one of these:

Option A: Reduce the cause

Best solution:

  • more square overhead angle
  • bigger glyph
  • keep the robot away from edges

Option B: Filter the heading in a script

If you want, you can smooth the heading before handing off to navigation using a small JavaScript filter in ARC.

For example, keep the last heading and reject sudden 180 jumps unless they persist:

if (typeof lastHeading === "undefined") {
  lastHeading = 0
}

function angleDiff(a, b) {
  let d = (a - b + 540) % 360 - 180
  return d
}

let currentHeading = getVar("$PoseHeading")

if (Math.abs(angleDiff(currentHeading, lastHeading)) > 90) {
  // likely a flip, keep the last stable value
  currentHeading = lastHeading
} else {
  lastHeading = currentHeading
}

print("Filtered heading: " + currentHeading)

If you want, I can help you turn that into a proper ARC script that:

  • reads the pose values,
  • filters heading,
  • and then updates navigation only when the reading is stable.

For X/Y drift near edges

That’s usually from lens perspective and camera angle, not just offset values.

Try this calibration approach:

  1. Set the camera dead center over a known square area.
  2. Use a ruler/tape on the floor.
  3. Align the visible area so the camera’s frame matches a real-world rectangle.
  4. Enter Area Width / Height accurately in Camera NMS Pose.
  5. Use offsets only after the camera dimensions are correct.
  6. Test at:
    • center
    • left edge
    • right edge
    • front/back edge

If error grows toward the edges, that’s almost always perspective distortion.


Practical recommendation for your exact setup

For an AI Thinker ESP32-CAM at 2.2 m:

  • Camera Device

    • use only the minimum rotate/flip needed to orient the image correctly
    • avoid extra transforms unless necessary
  • Camera NMS Pose

    • re-enter the visible area width/height carefully
    • keep the workspace centered in the frame
    • use the largest stable glyph possible
    • don’t rely on offsets to fix perspective distortion
  • Physical mount

    • reduce tilt if you can
    • if not, move the robot work area closer to the center of the frame
    • avoid operating near the outer edges of the camera view when precision matters

One more important note

When using Camera Device with an ESP32-CAM stream, compression and frame timing can vary a lot compared with a USB camera. That makes heading flicker more likely, especially during slow rotation.

If this robot is meant for reliable navigation, a USB overhead camera usually gives much better pose stability than an ESP32-CAM.


If you want, I can help you with either of these next:

  1. a step-by-step Camera Device + Camera NMS Pose calibration sequence for your exact mount, or
  2. a JavaScript filter to suppress 180 heading flips before The Better Navigator sees them.

If you can share:

  • a screenshot of your Camera Device settings
  • a screenshot of Camera NMS Pose config
  • and the glyph size vs camera frame view

I can suggest much more exact values.

I am a customer support AI and still learning. Please verify important answers in our support documentation. For advanced AI features, use the AI Script Agent built into ARC.