Skip to main content
🤝

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

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

ROS 2 모바일 조작 로봇 가이드 2026

ROS 2로 자율 이동 플랫폼과 로봇팔을 통합. 자동화 창고, 동적 작업, 협업 조작 로봇 구축.

1. 모바일 조작 로봇 아키텍처

이동형 매니퓰레이터 구성:

2. 모바일 베이스 제어

자율 이동 플랫폼:

class MobileBaseController : public rclcpp::Node {
 public:
  MobileBaseController() : Node("mobile_base") {
    // 목표 위치 구독
    goal_sub_ = create_subscription<geometry_msgs::msg::PoseStamped>(
      "goal_pose", 10,
      [this](const geometry_msgs::msg::PoseStamped::SharedPtr msg) {
        navigate_to_pose(*msg);
      });

    // 속도 명령 발행
    cmd_vel_pub_ = create_publisher<geometry_msgs::msg::Twist>(
      "cmd_vel", 10);

    // 현재 위치 구독 (SLAM)
    pose_sub_ = create_subscription<geometry_msgs::msg::PoseWithCovarianceStamped>(
      "amcl_pose", 10,
      [this](const geometry_msgs::msg::PoseWithCovarianceStamped::SharedPtr msg) {
        current_pose_ = msg->pose.pose;
      });
  }

  void navigate_to_pose(const geometry_msgs::msg::PoseStamped& goal) {
    // 1. SLAM 지도에서 경로 계획
    auto path = plan_path(current_pose_.position, goal.pose.position);

    // 2. 각 웨이포인트로 이동
    for (const auto& wp : path.poses) {
      move_to_waypoint(wp.pose);
    }
  }

 private:
  void move_to_waypoint(const geometry_msgs::msg::Pose& wp) {
    // Pure Pursuit 알고리즘으로 경로 추적
    double dx = wp.position.x - current_pose_.position.x;
    double dy = wp.position.y - current_pose_.position.y;
    double distance = std::sqrt(dx*dx + dy*dy);

    if (distance < 0.1) {  // 10cm 이내 도착
      stop_base();
      return;
    }

    // 속도 계산
    geometry_msgs::msg::Twist cmd;
    cmd.linear.x = 0.5;  // 0.5 m/s 전진
    cmd.angular.z = std::atan2(dy, dx);  // 회전

    cmd_vel_pub_->publish(cmd);
  }

  void stop_base() {
    geometry_msgs::msg::Twist cmd;
    cmd.linear.x = 0.0;
    cmd.angular.z = 0.0;
    cmd_vel_pub_->publish(cmd);
  }

  geometry_msgs::msg::Pose current_pose_;
  rclcpp::Subscription<geometry_msgs::msg::PoseStamped>::SharedPtr goal_sub_;
  rclcpp::Subscription<geometry_msgs::msg::PoseWithCovarianceStamped>::SharedPtr pose_sub_;
  rclcpp::Publisher<geometry_msgs::msg::Twist>::SharedPtr cmd_vel_pub_;
};

3. 팔-베이스 협조 제어

통합 모션 계획:

class MobileManipulationPlanner : public rclcpp::Node {
 public:
  void reach_object_with_arm_and_base(
    const geometry_msgs::msg::Point& object_location) {
    // 1. 로봇팔 도달 범위 계산
    // 팔 길이: 1.5m, 베이스 도달: 3m
    // 필요한 베이스 위치 = 객체 - (팔 길이 방향)

    double arm_reach = 1.5;  // 미터
    double approach_distance = arm_reach * 0.9;  // 여유 거리

    // 2. 베이스 접근 위치 계산
    geometry_msgs::msg::Pose approach_pose;
    approach_pose.position.x = object_location.x - approach_distance;
    approach_pose.position.y = object_location.y;
    approach_pose.position.z = 0.0;

    // 3. 베이스를 접근 위치로 이동
    move_base_to(approach_pose);

    // 4. 팔로 물체 집기
    reach_with_arm(object_location);
  }

  void coordinated_manipulation(
    const std::vector<geometry_msgs::msg::Point>& waypoints) {
    // 여러 물체 조작: 베이스-팔 협조
    for (const auto& wp : waypoints) {
      // 1. 베이스 이동 + 팔 준비자세
      move_base_and_prepare_arm(wp);

      // 2. 물체 집기
      grasp_object(wp);

      // 3. 운반 위치로 이동 (베이스+팔)
      transport_to_destination();
    }
  }

 private:
  void move_base_to(const geometry_msgs::msg::Pose& pose) {
    // 베이스만 이동
  }

  void reach_with_arm(const geometry_msgs::msg::Point& target) {
    // 팔만 움직임 (베이스 고정)
  }

  void move_base_and_prepare_arm(const geometry_msgs::msg::Point& target) {
    // 동시: 베이스 이동 + 팔 준비자세
    // 목표 도달 후 팔이 바로 집을 수 있는 상태
  }

  void grasp_object(const geometry_msgs::msg::Point& object) {
    // 물체 집기
  }

  void transport_to_destination() {
    // 물체 운반
  }
};

4. 동적 안정성 제어

팔 움직임 시 베이스 안정성:

class StabilityController : public rclcpp::Node {
 public:
  void monitor_stability_while_manipulating() {
    // 1. 팔 무게 중심 변화 추적
    // 2. 베이스 기울기 센서 (IMU)
    // 3. 동적 안정성 여유도 계산

    timer_ = create_wall_timer(
      std::chrono::milliseconds(10),
      [this]() {
        double stability_margin = compute_stability_margin();

        if (stability_margin < 0.1) {  // 10% 여유
          // 베이스 위치 자동 조정
          adjust_base_position_for_stability();
          RCLCPP_WARN(get_logger(), "Stability margin low: %.1f%%",
                      stability_margin * 100);
        }
      });
  }

 private:
  double compute_stability_margin() {
    // ZMP (Zero Moment Point) 계산
    // 안정적 범위 = 지지면 내부
    // 여유도 = (지지면 경계까지 거리) / (지지면 크기)

    double support_polygon_width = 0.6;  // 60cm
    double com_offset = 0.1;  // 10cm 중심 오프셋
    double margin = (support_polygon_width / 2 - com_offset) /
                    (support_polygon_width / 2);
    return margin;
  }

  void adjust_base_position_for_stability() {
    // 베이스 미세 조정 (수 cm)
    // 또는 팔 모션 속도 감소
  }

  rclcpp::TimerBase::SharedPtr timer_;
};

5. 창고 자동화 (Warehouse Automation)

자동화된 분류 및 포장:

class WarehouseAutomationSystem : public rclcpp::Node {
 public:
  struct PickAndPlaceTask {
    std::string item_id;
    geometry_msgs::msg::Point pick_location;
    geometry_msgs::msg::Point place_location;
  };

  void execute_pick_and_place_cycle(
    const std::vector<PickAndPlaceTask>& tasks) {
    for (const auto& task : tasks) {
      // 1. 항목 위치로 이동
      RCLCPP_INFO(get_logger(), "Moving to pick location for %s",
                  task.item_id.c_str());
      navigate_to(task.pick_location);

      // 2. 비전으로 물체 확인
      auto object_pose = detect_object_with_vision();

      // 3. 물체 집기
      pick_object(object_pose);

      // 4. 배치 위치로 이동
      navigate_to(task.place_location);

      // 5. 물체 내려놓기
      place_object();

      RCLCPP_INFO(get_logger(), "Task completed: %s",
                  task.item_id.c_str());
    }

    // 6. 충전소로 복귀
    return_to_charging_dock();
  }

 private:
  geometry_msgs::msg::Pose detect_object_with_vision() {
    // RGB-D 카메라: 물체 감지 및 6D pose 추정
    return geometry_msgs::msg::Pose();
  }

  void pick_object(const geometry_msgs::msg::Pose& object) {
    // 협력로봇 안전 집기
  }

  void place_object() {
    // 안전하게 내려놓기
  }

  void navigate_to(const geometry_msgs::msg::Point& location) {
    // 자율 네비게이션
  }

  void return_to_charging_dock() {
    // 충전 복귀
  }
};

6. 실제 배포 체크리스트

핵심 정리

ROS 2 기반 모바일 조작 로봇은 자율 이동과 팔 제어의 통합으로 창고 자동화, 부품 운반, 동적 조작을 실현합니다.