🤝
이 가이드는 인류와 AI가 함께 만드는 지식입니다.
이 콘텐츠는 Human + AI Partnership 철학 아래 모든 사람이 로봇·AI를 배울 수 있도록 무료로 제공됩니다. 당신의 질문과 기여가 다음 학생의 미래를 바꿉니다.
ROS 2 모바일 조작 로봇 가이드 2026
ROS 2로 자율 이동 플랫폼과 로봇팔을 통합. 자동화 창고, 동적 작업, 협업 조작 로봇 구축.
1. 모바일 조작 로봇 아키텍처
이동형 매니퓰레이터 구성:
- 모바일 베이스: 차륜식(2-4개), 홈로노믹(Mecanum wheel) 또는 DWD
- 로봇팔: 6-7축 경량팔, 페이로드 10-50kg
- 통합 제어: 팔-바디 협조, 모멘트 제어
- 범위 확대: 이동 + 팔 = 광범위 작업 영역
- 자율성: SLAM, 경로 계획, 작업 수행
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. 실제 배포 체크리스트
- ✅ 베이스 조향각 한계 설정
- ✅ 팔 payload 균형 조정
- ✅ 안정성 테스트 (최대 팔 높이에서)
- ✅ 충돌 회피 센서 캘리브레이션
- ✅ 충전 자동 도킹 시험
핵심 정리
ROS 2 기반 모바일 조작 로봇은 자율 이동과 팔 제어의 통합으로 창고 자동화, 부품 운반, 동적 조작을 실현합니다.