Conversation
RtspCamera (dimos/hardware/sensors/camera/rtsp): RTSP URL, file or a generated clip in; video (encoded, untouched), color_image and color_jpeg out. PyAV only, url is required, set_video_enabled() and set_jpeg_rate() are RPCs. Blueprint rtsp-camera-vis. SiyiA8Gimbal (dimos/hardware/gimbal/siyi): gimbal tf chain, camera_info (a8_camera_info() is the one source of the A8 intrinsics), aim requests on gimbal_target. ip is a config field with no default; with it set the SIYI SDK client polls the zoom and camera_info is withheld off 1x. New px4 extra: av. Tests: pytest dimos/hardware/gimbal/siyi dimos/hardware/sensors/camera/rtsp -> 37 passed (gimbal 22, camera 15).
sensor_msgs.NavSatFix and sensor_msgs.BatteryState wrap the dimos_lcm types and take their enum values from them. px4_msgs.VehicleStatus is a hand-written LCM type with the wire layout of sensor_msgs/ImuInfo (fingerprint, Header, big-endian fields); its base hash is an arbitrary constant, there is no .lcm schema. The wire helpers are in dimos/msgs/lcm_wire.py. No registry, pyproject or lock change. The producer is Px4DroneConnection in the next commit: its gps, battery and vehicle_status outputs. Tests: pytest dimos/msgs/px4_msgs dimos/msgs/sensor_msgs/test_NavSatFix.py dimos/msgs/sensor_msgs/test_BatteryState.py -> 6 passed (43 with the payload tests below).
|
| self.relay_once() | ||
| except (av.FFmpegError, OSError, IndexError, ValueError) as exc: | ||
| self._count("video", errors=1) | ||
| logger.warning("camera stream unavailable", url=self._source, error=str(exc)) |
There was a problem hiding this comment.
If an RTSP URL contains a password, a connection failure logs the full URL to console output and the structured log; the stream-closure warning at line 185 does the same. Anyone with access to those logs can read the credential. Redact credentials in both warnings without changing the URL used to connect. This must be fixed before merging.
How this was verified: Both warning paths wrote a password-bearing URL to console output and structured logs.
Artifacts
Isolated RTSP credential logging reproduction script
- The executed script drives both camera logging branches with an offline password-bearing URL and checks the resulting JSON events.
Camera logs with the unmodified logger
- Running both branches with the unmodified logger produced console and JSON entries containing the test password.
Camera logs with process-local URL sanitization
- Running the same branches with an isolated sanitizing logger produced entries without the password, showing a viable redaction boundary.
| # MAVLink gimbal angles: yaw clockwise positive, pitch up positive; FLU is the reverse. | ||
| gimbal_rot = Quaternion.from_euler( | ||
| Vector3( | ||
| math.radians(att.roll_deg), -math.radians(att.pitch_deg), -math.radians(att.yaw_deg) | ||
| ) | ||
| ) |
There was a problem hiding this comment.
Aircraft tilt misorients camera
When the aircraft pitches or rolls, the A8 reports earth-stabilized attitude, but this code publishes it as a rotation relative to the aircraft. The camera transform then points observations and targets in the wrong direction: with 20° aircraft pitch and zero reported earth pitch, the published camera orientation is 20° off. Convert the reported attitude into the aircraft frame before publishing it. This must be fixed before merging.
Artifacts
Executable SIYI frame comparison script
- This authored script feeds synthetic attitudes through the real TF publisher and compares published and physically expected camera rotations.
Published TF with nonlevel aircraft attitude
- Running the script in before mode shows 20° pitch error and 24.954° combined pitch-and-roll error in the published camera orientation.
Physical body-relative rotation with nonlevel aircraft attitude
- Running the same inputs with the expected body-relative rotation substituted in the comparison reduces camera-orientation error to approximately zero.
- Running the focused SIYI test file passes all 22 tests, showing that its existing coverage does not catch this nonlevel-aircraft error.
| self.video.publish( | ||
| CompressedVideo(bytes(unit), format="h265", frame_id=self.config.frame_id, ts=ts) | ||
| ) | ||
| self._count("video", published=1) |
There was a problem hiding this comment.
If the file-replay filter emits zero or multiple packets from one call, this counter still increases by one. sensor_stats() and interval-rate logs can then disagree with the video messages sent, making diagnostics misleading. The tested native filter emitted one packet per call, so that clip was unaffected. Count successful publications inside the loop. This diagnostic concern is non-blocking.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Artifacts
Full authored H.265 replay and publish-count reproduction script
- The complete executed Python source generates a clip, records filter output and publication counts, and applies an in-memory correction for comparison.
Replay output with the repository publish counter
- The captured command, working directory, exit code, and output show ten per-call mismatches with buffered zero/two-packet output, while the native one-packet output matches.
Replay output with an in-memory per-packet counter
- The captured command, working directory, exit code, and output show no per-call mismatches after moving the increment inside the publication loop in memory.
Comments Outside DiffThese findings sit on lines the diff does not cover, so they could not be posted inline. Each one leaves this list once its file changes.
|
What is this feature?
Message types the PX4 connection publishes.
sensor_msgs/NavSatFix,sensor_msgs/BatteryState: wrappers over thedimos_lcmtypes.px4_msgs/VehicleStatus: armed, PX4 mode, landed state, battery, GPS quality, supervisor state. Hand-written LCM type (its proper home is dimos-lcm). Wire helpers indimos/msgs/lcm_wire.py.Why do we need this?
Px4DroneConnection(#4291) publishesgps,batteryandvehicle_status. Split out to keep that PR about flight code.How to Test
Round trips compare whole messages; a foreign fingerprint is refused.
Stack
Five PRs, all against
main; each contains the ones above it. Merge in order. Review only this PR's own commit: c711bdfWhich issue(s) does this PR close?
None. New platform: PX4 multicopters with a SIYI A8 gimbal camera.
Checklist
🤖 Generated with Claude Code