Skip to main content
🤝

이 가이드는 인류와 AI가 함께 만드는 지식입니다.

이 콘텐츠는 Human + AI Partnership 철학 아래 모든 사람이 로봇·AI를 배울 수 있도록 무료로 제공됩니다. 당신의 질문과 기여가 다음 학생의 미래를 바꿉니다.

ROS 2 수중로봇(ROV/AUV) 가이드 2026

ROS 2로 ROV(원격조종)·AUV(자율) 수중 로봇 개발. 수중 통신, 센서 융합, 자율 내비게이션, 해양 탐사 시스템 구축.

1. 수중 로봇 아키텍처

수중 로봇 시스템 설계:

2. 수중 통신 (모뎀 제어)

수중 음파 모뎀 통신:

// 수중 음파 모뎀 ROS 2 인터페이스
class UnderwaterModemDriver : public rclcpp::Node {
 public:
  UnderwaterModemDriver() : Node("modem_driver") {
    // 모뎀 시리얼 연결
    modem_sub_ = create_subscription<std_msgs::msg::String>(
      "modem_rx", 10,
      [this](const std_msgs::msg::String::SharedPtr msg) {
        parse_acoustic_message(*msg);
      });

    modem_pub_ = create_publisher<std_msgs::msg::String>(
      "modem_tx", 10);
  }

 private:
  void parse_acoustic_message(const std_msgs::msg::String& msg) {
    // 수중 통신 지연: 1500m/s (음속)
    // 패킷: [DEST_ID] [TIMESTAMP] [PAYLOAD] [CHECKSUM]
    double sound_speed = 1500.0;  // m/s 해수
    double range = 5000.0;  // 5km 통신 범위
    double latency = range / sound_speed;  // ~3.3초

    RCLCPP_INFO(get_logger(), "Acoustic RX from vehicle: %s (latency: %.1fs)",
                msg.data.c_str(), latency);
  }

  void send_acoustic_command(const std::string& cmd) {
    // 모뎀으로 음파 전송
    std_msgs::msg::String msg;
    msg.data = cmd;
    modem_pub_->publish(msg);
  }

  rclcpp::Subscription<std_msgs::msg::String>::SharedPtr modem_sub_;
  rclcpp::Publisher<std_msgs::msg::String>::SharedPtr modem_pub_;
};

3. 수중 센서 융합 (USBL/DVL)

위치 결정 센서:

class UnderwaterNavigationFusion : public rclcpp::Node {
 private:
  // USBL: Ultra Short Baseline 음파 위치결정
  // DVL: Doppler Velocity Log 속도 측정
  Eigen::VectorXd state_;  // [x, y, z, vx, vy, vz, heading]
  Eigen::MatrixXd covariance_;

 public:
  void update_with_usbl(const geometry_msgs::msg::PointStamped& position) {
    // USBL 위치 업데이트 (정확도 ±수미터)
    Eigen::Vector3d measurement(
      position.point.x,
      position.point.y,
      position.point.z);

    double usbl_noise = 2.0;  // 2m 표준편차
    update_kalman(measurement, usbl_noise);
  }

  void update_with_dvl(const geometry_msgs::msg::TwistStamped& velocity) {
    // DVL 속도 업데이트 (정확도 0.2%)
    Eigen::Vector3d velocity_meas(
      velocity.twist.linear.x,
      velocity.twist.linear.y,
      velocity.twist.linear.z);

    update_velocity(velocity_meas);
  }

  void update_with_imu_compass(
    const sensor_msgs::msg::Imu& imu,
    const sensor_msgs::msg::MagneticField& compass) {
    // IMU + 나침반으로 방향 보정
    double heading = compute_heading(compass);
    state_(6) = heading;  // 헤딩 업데이트
  }

  // 확장 칼만 필터
  void update_kalman(const Eigen::Vector3d& meas, double noise) {
    // USBL 센서 모델
    // H = [1 0 0 0 0 0 0; 0 1 0 0 0 0 0; 0 0 1 0 0 0 0]
    // 측정 = position (z 무시가능)
  }
};

4. 자율 내비게이션 (SLAM 수중)

수중 SLAM 알고리즘:

# 수중 SLAM 패키지 설치 및 실행
ros2 install ros-humble-fssf-slam  # Forward-Scanning Sonar SLAM
ros2 install ros-humble-slam-toolbox

# SLAM 설정 파일 (underwater_slam.yaml)
slam_toolbox:
  plugins:
    slam_toolbox_mappingsf:
      plugin: slam_toolbox/SerialAsyncSlamToolbox
  # 수중 특화 파라미터:
  correlation_search_space_dimension: 0.5  # 50cm 해상도
  correlation_search_space_resolution: 0.05  # 5cm 격자
  loop_search_space_dimension: 20.0  # 20m 루프 클로저 감지

# 음향 이미징 소나 SLAM 실행
ros2 launch slam_toolbox online_async_launch.py   slam_params_file:=underwater_slam.yaml

5. 원격 조종 (ROV 제어)

케이블 ROV 실시간 제어:

class RemoteOperatedVehicle : public rclcpp::Node {
 public:
  RemoteOperatedVehicle() : Node("rov_controller") {
    // 조이스틱 입력
    joy_sub_ = create_subscription<sensor_msgs::msg::Joy>(
      "joy", 10,
      [this](const sensor_msgs::msg::Joy::SharedPtr msg) {
        handle_joystick_input(*msg);
      });

    // 6DOF 추력기 명령어
    thruster_pub_ = create_publisher<std_msgs::msg::Float64MultiArray>(
      "rov_thrusters", 10);

    // 카메라/조명 제어
    light_pub_ = create_publisher<std_msgs::msg::Float32>(
      "rov_light_intensity", 10);
  }

 private:
  void handle_joystick_input(const sensor_msgs::msg::Joy& joy) {
    // 조이스틱 맵핑:
    // axes[0] = 전진/후진
    // axes[1] = 좌/우 (yaw)
    // axes[2] = 상승/하강
    // buttons[0] = 그리퍼 열기
    // buttons[1] = 그리퍼 닫기

    std_msgs::msg::Float64MultiArray thruster_cmd;
    thruster_cmd.data.resize(8);  // 8개 추력기

    // 수압 보정: 깊이에 따라 중성부력 조정
    double depth = current_depth_;  // 미터
    double pressure_compensation = depth * 1025 * 9.81 / 1000;  // kg·m/s²

    // 추력기 분배 알고리즘 (8-DOF vector allocation)
    allocate_thrusts(joy, pressure_compensation, thruster_cmd.data);
    thruster_pub_->publish(thruster_cmd);
  }

  rclcpp::Subscription<sensor_msgs::msg::Joy>::SharedPtr joy_sub_;
  rclcpp::Publisher<std_msgs::msg::Float64MultiArray>::SharedPtr thruster_pub_;
  rclcpp::Publisher<std_msgs::msg::Float32>::SharedPtr light_pub_;
  double current_depth_ = 0.0;
};

6. AUV 자율 경로 계획

사전 프로그램 탐사 경로:

class AUVMissionPlanner : public rclcpp::Node {
 public:
  struct MissionWaypoint {
    double latitude, longitude;
    double depth;
    double heading;
    int action;  // 0=항해, 1=샘플링, 2=촬영
  };

  void execute_mission(const std::vector<MissionWaypoint>& waypoints) {
    for (const auto& wp : waypoints) {
      // 위치 도착
      navigate_to_waypoint(wp);

      // 임무 수행
      if (wp.action == 1) {
        collect_sample();  // 샘플 수집
      } else if (wp.action == 2) {
        capture_image();  // 사진 촬영
      }

      // 배터리 상태 확인
      if (get_battery_percent() < 20.0) {
        abort_mission_return_to_surface();
      }
    }
  }

 private:
  void navigate_to_waypoint(const MissionWaypoint& target) {
    // 1. GPS → UTM 변환 (선상)
    // 2. GPS-거부 해역: DVL + 나침반 무향법
    // 3. 도착 기준: 수평거리 ±2m, 깊이 ±0.5m
  }

  void abort_mission_return_to_surface() {
    // 비상 상승 (긍정 부력으로 해수면 복귀)
    RCLCPP_WARN(get_logger(), "Battery critical - returning to surface");
    set_positive_buoyancy();
  }
};

7. 수중 장애물 회피 (Sonar)

소나 기반 장애물 감지:

class SonarObstacleAvoidance : public rclcpp::Node {
 public:
  SonarObstacleAvoidance() : Node("sonar_avoidance") {
    sonar_sub_ = create_subscription<sensor_msgs::msg::LaserScan>(
      "sonar_scan", 10,
      [this](const sensor_msgs::msg::LaserScan::SharedPtr msg) {
        detect_obstacles(*msg);
      });

    trajectory_pub_ = create_publisher<nav_msgs::msg::Path>(
      "obstacle_free_path", 10);
  }

 private:
  void detect_obstacles(const sensor_msgs::msg::LaserScan& scan) {
    // 소나 스캔 분석
    // 범위: 0.5-100m, 해상도: 1-2도
    double danger_distance = 5.0;  // 5m 이상 접근 금지

    std::vector<double> obstacle_angles;
    for (size_t i = 0; i < scan.ranges.size(); ++i) {
      if (scan.ranges[i] < danger_distance && scan.ranges[i] > scan.range_min) {
        double angle = scan.angle_min + i * scan.angle_increment;
        obstacle_angles.push_back(angle);
      }
    }

    // 회피 경로 계산: VFM (Vector Field Method)
    nav_msgs::msg::Path safe_path = compute_vector_field(obstacle_angles);
    trajectory_pub_->publish(safe_path);
  }

  nav_msgs::msg::Path compute_vector_field(
    const std::vector<double>& obstacle_angles) {
    // 인력장: 목표 방향
    // 척력장: 장애물 반대 방향
    // 합성장: 안전 경로
    nav_msgs::msg::Path path;
    return path;
  }

  rclcpp::Subscription<sensor_msgs::msg::LaserScan>::SharedPtr sonar_sub_;
  rclcpp::Publisher<nav_msgs::msg::Path>::SharedPtr trajectory_pub_;
};

8. 해양 환경 시뮬레이션

Gazebo 수중 물리 엔진:

# UUV Simulator 플러그인 설치 (Gazebo 수중 전문)
ros2 install ros-humble-uuv-simulator
ros2 install ros-humble-freefloating-gazebo

# 수중 환경 설정 (underwater_world.world)
<sdf version="1.9">
  <world name="underwater_world">
    <!-- 유체 역학 -->
    <plugin name="ocean_current" filename="libOceanCurrentPlugin.so">
      <current_velocity>0.2 0.0 0.0</current_velocity>  <!-- 0.2 m/s 동쪽 흐름 -->
    </plugin>

    <!-- 조명 (수심 감소)-->
    <light name="sun" type="directional">
      <intensity>0.5</intensity>  <!-- 수중 어두움 -->
    </light>

    <!-- 해저 지형 -->
    <model name="seafloor">
      <static>true</static>
      <mesh>seafloor.dae</mesh>  <!-- 3D 해저 지형
    </model>
  </world>
</sdf>

# 시뮬레이션 실행
ros2 launch uuv_simulator one_auv_two_thrusters.launch.py

9. 실제 배포 체크리스트

10. 국제 표준 & 규제

수중 로봇 준수 사항:

핵심 정리

ROS 2 기반 수중 로봇 시스템은 음파 통신, 센서 융합, 자율 내비게이션을 통해 심해 탐사·해양 연구·해양자원 개발을 실현합니다. ROV 원격 제어와 AUV 자율 운영의 조화가 해양 로보틱스의 미래입니다.