<aside> 📘

POSIM — Platform for Ocean Simulation · documentation checked 2026-10-01

Target: ROS 2 Lyrical / Gazebo Jetty. Current source. Compatibility names such as dave_* are intentional. Start with POSIM Installation and POSIM Quickstart & Backend Support.

Source documentation and inherited illustrations do not certify every runtime configuration. Published Docker candidates, development main, and experimental WGPU are distinct states.

</aside>

Before the examples, source ROS and the matching workspace using POSIM Native Installation or POSIM Docker Guide. Commands containing ~/posim_ws below refer to a native source workspace; in a prebuilt container use its documented $POSIM_WS/install/setup.bash instead. Existing illustrations are retained from the DAVE documentation and are not new POSIM runtime captures.

Overview

Underwater imagery differs from surface imagery due to several factors:

  1. Light Absorption: Water absorbs light, especially red wavelengths, much more quickly than air. As a result, underwater scenes tend to be dominated by blue and green hues, with reds appearing faded or absent at greater depths.
  2. Scattering: Water particles scatter light in all directions, reducing clarity and contrast. This scattering makes underwater images appear hazier and less sharp than those taken in air, particularly in murky waters.
  3. Color Shift: As depth increases, the color spectrum shifts. Reds and oranges are lost first, followed by yellows and greens. At deeper levels, everything appears bluish or greenish, with a significant loss of color variety.
  4. Reduced Visibility: Suspended particles, plankton, and other substances in water reduce visibility, leading to a foggy or cloudy appearance in images, particularly in coastal or murky waters.
  5. Limited Light Penetration: Unlike air, water significantly reduces the amount of light that penetrates, making deep underwater environments much darker and requiring artificial lighting for clear images.

These are background properties of real underwater imagery. The POSIM plugin implements a depth-based per-channel attenuation/background model; the list above is not a claim that every scattering or lighting mechanism is physically simulated.

Example Usage

  1. Create a camera sensor of type RGB-D and attach the plugin to the model.sdf file as shown below:

    <sensor name="underwater_camera" type="rgbd_camera">
      <update_rate>10</update_rate>
      <visualize>true</visualize>
      <always_on>1</always_on>
      <topic>underwater_camera</topic>
      <camera>
        <horizontal_fov>1.05</horizontal_fov>
        <image>
          <width>320</width>
          <height>240</height>
        </image>
        <clip>
          <near>0.1</near>
          <far>10.0</far>
        </clip>
      </camera>
      <plugin
        filename="UnderwaterCamera"
        name="dave_gz_sensor_plugins::UnderwaterCamera">
        <attenuationR>0.8</attenuationR>
        <attenuationG>0.5</attenuationG>
        <attenuationB>0.2</attenuationB>
        <!-- Murky Coastal Waters -->
        <backgroundR>85</backgroundR>
        <backgroundG>107</backgroundG>
        <backgroundB>47</backgroundB>
      </plugin>
    </sensor>
    

    Description of the UnderwaterCamera plugin arguments:

    Argument Description Default Value
    attenuationR Attenuation coefficient applied to the output red channel in POSIM main. 0.0333 (1/30)
    attenuationG Attenuation coefficient applied to the output green channel in POSIM main. 0.0333 (1/30)
    attenuationB Attenuation coefficient applied to the output blue channel in POSIM main. 0.0333 (1/30)
    backgroundR Background intensity applied to the output red channel in POSIM main. Range 0–255 (unsigned char). 0
    backgroundG Background intensity applied to the output green channel in POSIM main. Range 0–255 (unsigned char). 0
    backgroundB Background intensity applied to the output blue channel in POSIM main. Range 0–255 (unsigned char). 0
  2. Build and source the workspace:

    source /opt/ros/lyrical/setup.bash
    source ~/posim_ws/install/setup.bash
    
  3. Launch the camera in an underwater setting:

    ros2 launch dave_demos dave_sensor.launch.py namespace:=underwater_camera world_name:=camera_tutorial paused:=false x:=10 z:=-93.5 pitch:=0.3 yaw:=3.14 gui:=false headless:=true
    

    <aside> ⚠️

    Important launch arguments:

    Argument Name Description Default Value
    namespace Packaged sensor descriptor; select underwater_camera here. See installed source catalog. “”
    world_name Gazebo world file to launch (use camera_tutorial to test the underwater camera) empty.sdf
    paused Start the simulation paused true
    debug Enables verbose mode for Gazebo simulation false
    verbosity_level Gazebo verbosity level when debug is enabled (0–4) 1
    x Initial x position [m] 0.0
    y Initial y position [m] 0.0
    z Initial z position [m] 0.0
    roll Initial roll angle [rad] 0.0
    pitch Initial pitch angle [rad] 0.0
    yaw Initial yaw angle [rad] 0.0
    </aside>

    Screenshot 2024-09-01 at 3.15.18 AM.png

  4. Open another terminal, source the workspace and check for available ROS 2 topics:

    source /opt/ros/lyrical/setup.bash
    source ~/posim_ws/install/setup.bash
    ros2 topic list
    

    It should produce an output similar to:

    Screenshot 2024-09-01 at 3.16.17 AM.png

  5. In a terminal with a configured GUI display, source the workspace and view the image with image_view. This viewer is optional and is not part of headless validation. For server-only inspection use ros2 topic info /underwater_camera/simulated_image and receive a payload instead.

    source /opt/ros/lyrical/setup.bash
    source ~/posim_ws/install/setup.bash
    ros2 run image_view image_view --ros-args -r image:=/underwater_camera/simulated_image
    

    Example 1: No effects

(These are explicit overrides. Leaving the tags out gives 0.0333 per channel, not 0.0.)

Argument Value
attenuationR 0.0
attenuationG 0.0
attenuationB 0.0
backgroundR 0
backgroundG 0
backgroundB 0

Screenshot 2024-09-01 at 3.23.49 AM.png