payload.modes.PayloadWaitForDriveOutMode#

PayloadWaitForDriveOutMode — waits until the plane has landed on the DLZ.

Primary detection: HSV orange mask — does the camera see the orange DLZ?

When orange coverage >= orange_pixel_threshold continuously for wait_seconds, the plane is confirmed landed → transition to reverse. Optical flow is NOT checked while orange is visible (moving objects in the background cannot disturb the timer).

Optical flow is only used when orange is absent: if the frame is still but no orange is visible, the camera may be obstructed (plane belly, etc.) → obstruction retreat. Optical flow state is reset whenever orange disappears so readings are fresh after a landing.

CV runs inline (no separate vision node). The v4l2 + camera nodes still launch.

Transitions:

“complete” -> whatever drive-out mode is configured in the mission YAML

Classes#

PayloadWaitForDriveOutParams

DriveOutState

Create a collection of name/value pairs.

PayloadWaitForDriveOutMode

Subscribe to the payload camera and detect when the plane has landed on the

Module Contents#

class PayloadWaitForDriveOutParams#

Bases: vehicle_common.mode_loader.ParamsBase

dlz_color_lower_hsv: List[int] = (5, 120, 120)#
dlz_color_upper_hsv: List[int] = (20, 255, 255)#
dlz_color_pixel_threshold: float = 0.04#
stillness_threshold: float = 2.0#
stillness_window: int = 15#
stillness_flow_crop_frac: float = 0.4#
obstruction_retreat_linear: float = -0.05#
obstruction_retreat_speed: float = 1.5#
obstruction_retreat_timeout_sec: float = 0.2#
dlz_color_wait_seconds: float = 7.0#
obstruction_frames: int = 20#
turn_angular: float = 3.141592653589793#
turn_speed: float = 1.85#
compressed_image: bool = False#
debug: bool = False#
class DriveOutState(*args, **kwds)#

Bases: enum.Enum

Create a collection of name/value pairs.

Example enumeration:

>>> class Color(Enum):
...     RED = 1
...     BLUE = 2
...     GREEN = 3

Access them by:

  • attribute access:

    >>> Color.RED
    <Color.RED: 1>
    
  • value lookup:

    >>> Color(1)
    <Color.RED: 1>
    
  • name lookup:

    >>> Color['RED']
    <Color.RED: 1>
    

Enumerations can be iterated over, and know how many members they have:

>>> len(Color)
3
>>> list(Color)
[<Color.RED: 1>, <Color.BLUE: 2>, <Color.GREEN: 3>]

Methods can be added to enumerations, and members can have their own attributes – see the documentation for details.

WAIT_UNREEL = 0#
OBSTRUCTION_RETREAT = 1#
REVERSING = 2#
TURNING = 3#
DONE = 4#
class PayloadWaitForDriveOutMode#

Bases: vehicle_common.mode.Mode

Subscribe to the payload camera and detect when the plane has landed on the DLZ. Confirmation requires BOTH:

  1. Orange HSV coverage >= orange_pixel_threshold (DLZ visible)

  2. Frame optical-flow magnitude < stillness_threshold (payload not moving)

Both conditions must hold continuously for wait_seconds before proceeding.

required_vision_nodes = ()#
requires_camera = True#
transition_labels = ('complete',)#
initialize(node: rclpy.node.Node, vehicle: payload.payload.Payload, params: PayloadWaitForDriveOutParams) None#
_on_image(msg: sensor_msgs.msg.Image) None#
_on_compressed_image(msg: sensor_msgs.msg.CompressedImage) None#
_get_bgr_frame() numpy.ndarray | None#
_now() float#
_check_orange(bgr: numpy.ndarray) tuple[bool, float, numpy.ndarray]#
_check_stillness(bgr: numpy.ndarray) bool#
_publish_debug(bgr: numpy.ndarray, orange_found: bool, coverage: float, orange_mask: numpy.ndarray, is_still: bool | None) None#

Publish debug image. is_still=None when orange is found (optical flow not run).

on_enter() None#
on_update(time_delta: float) None#
check_status() str#
on_exit() None#