본문으로 건너뛰기

ALICE4 코드 예제

ALICE4 로봇을 프로그래밍하는 실제 예제들을 소개합니다.

🏗️ 개발 환경 설정

ROS2 워크스페이스 생성

# 워크스페이스 생성
mkdir -p ~/alice4_ws/src
cd ~/alice4_ws/src

# ALICE4 패키지 클론
git clone https://github.com/aeirobot/alice4_msgs.git
git clone https://github.com/aeirobot/alice4_control.git

# 의존성 설치
cd ~/alice4_ws
rosdep install --from-paths src --ignore-src -r -y

# 빌드
colcon build --symlink-install
source install/setup.bash

Python 환경 설정

# 가상환경 생성 (선택사항)
python3 -m venv alice4_env
source alice4_env/bin/activate

# 필수 패키지 설치
pip install rclpy
pip install numpy
pip install matplotlib

📝 기본 예제

1. 로봇 상태 모니터링

#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from sensor_msgs.msg import JointState
from alice4_msgs.msg import RobotStatus

class Alice4Monitor(Node):
def __init__(self):
super().__init__('alice4_monitor')

# 조인트 상태 구독
self.joint_sub = self.create_subscription(
JointState,
'/alice4/joint_states',
self.joint_callback,
10
)

# 로봇 상태 구독
self.status_sub = self.create_subscription(
RobotStatus,
'/alice4/status',
self.status_callback,
10
)

def joint_callback(self, msg):
self.get_logger().info(f'Joint positions: {msg.position}')

def status_callback(self, msg):
status_text = "Ready" if msg.ready else "Not Ready"
self.get_logger().info(f'Robot status: {status_text}')

def main(args=None):
rclpy.init(args=args)
monitor = Alice4Monitor()
rclpy.spin(monitor)
monitor.destroy_node()
rclpy.shutdown()

if __name__ == '__main__':
main()

2. 간단한 움직임 제어

포인트 투 포인트 이동

#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from trajectory_msgs.msg import JointTrajectory, JointTrajectoryPoint
import math

class Alice4Mover(Node):
def __init__(self):
super().__init__('alice4_mover')

self.trajectory_pub = self.create_publisher(
JointTrajectory,
'/alice4/joint_trajectory_controller/joint_trajectory',
10
)

def move_to_position(self, joint_positions, duration=2.0):
# 트래젝토리 메시지 생성
trajectory = JointTrajectory()
trajectory.joint_names = [
'joint_1', 'joint_2', 'joint_3',
'joint_4', 'joint_5', 'joint_6'
]

# 포인트 생성
point = JointTrajectoryPoint()
point.positions = joint_positions
point.velocities = [0.0] * 6
point.time_from_start.sec = int(duration)
point.time_from_start.nanosec = int((duration % 1) * 1e9)

trajectory.points.append(point)

# 트래젝토리 발행
self.trajectory_pub.publish(trajectory)
self.get_logger().info('Trajectory published')

def main(args=None):
rclpy.init(args=args)

mover = Alice4Mover()

# 홈 포지션으로 이동 (모든 조인트 0도)
home_position = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
mover.move_to_position(home_position, 3.0)

# 2초 대기 후 종료
rclpy.spin_once(mover, timeout_sec=2.0)
mover.destroy_node()
rclpy.shutdown()

if __name__ == '__main__':
main()

3. 그리퍼 연동 예제

#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from std_msgs.msg import Float64
import time

class PickAndPlaceDemo(Node):
def __init__(self):
super().__init__('pick_and_place_demo')

# 그리퍼 제어 퍼블리셔
self.gripper_pub = self.create_publisher(
Float64,
'/alice4/gripper_controller/command',
10
)

# 조인트 트래젝토리 퍼블리셔 (위 예제 참고)
# self.trajectory_pub = ...

def open_gripper(self):
cmd = Float64()
cmd.data = 0.08 # 열린 상태 (미터)
self.gripper_pub.publish(cmd)
self.get_logger().info('Gripper opened')

def close_gripper(self):
cmd = Float64()
cmd.data = 0.0 # 닫힌 상태
self.gripper_pub.publish(cmd)
self.get_logger().info('Gripper closed')

def pick_sequence(self):
"""픽 앤 플레이스 시퀀스"""
# 1. 그리퍼 열기
self.open_gripper()
time.sleep(1)

# 2. 픽 포지션으로 이동
pick_position = [0.3, 0.2, 0.1, 0.0, 1.57, 0.0]
self.move_to_position(pick_position)

# 3. 그리퍼 닫기 (물체 잡기)
time.sleep(1)
self.close_gripper()
time.sleep(1)

# 4. 플레이스 포지션으로 이동
place_position = [0.1, -0.2, 0.3, 0.0, 1.57, 0.0]
self.move_to_position(place_position)

# 5. 그리퍼 열기 (물체 놓기)
time.sleep(1)
self.open_gripper()

# move_to_position 메서드는 위 예제 참고

🔧 고급 예제

경로 계획 및 실행

import numpy as np
from alice4_motion import MotionPlanner

class PathPlannerDemo:
def __init__(self):
self.planner = MotionPlanner()
self.planner.load_robot_model('alice4.urdf')

def plan_cartesian_path(self, waypoints):
"""직교 좌표계 웨이포인트들 사이의 경로 계획"""
path = []

for i in range(len(waypoints) - 1):
start = waypoints[i]
end = waypoints[i + 1]

# 직선 경로 생성 (간단한 예제)
num_points = 50
for t in np.linspace(0, 1, num_points):
point = start + t * (end - start)
path.append(point)

return path

def execute_path(self, cartesian_path):
"""계획된 경로 실행"""
joint_path = []

for pose in cartesian_path:
# 역기구학으로 조인트 각도 계산
joint_angles = self.planner.inverse_kinematics(pose)
if joint_angles is not None:
joint_path.append(joint_angles)

# 조인트 트래젝토리로 변환하여 실행
# (실제 구현에서는 속도/가속도 프로필 고려)
return joint_path

# 사용 예제
if __name__ == '__main__':
demo = PathPlannerDemo()

# 웨이포인트 정의 (x, y, z, rx, ry, rz)
waypoints = [
[0.3, 0.0, 0.2, 0.0, 3.14, 0.0],
[0.3, 0.2, 0.2, 0.0, 3.14, 0.0],
[0.1, 0.2, 0.3, 0.0, 3.14, 0.0],
]

# 경로 계획 및 실행
cartesian_path = demo.plan_cartesian_path(waypoints)
joint_trajectory = demo.execute_path(cartesian_path)

시뮬레이션 환경 설정

# simulation.launch.py
from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
import os

def generate_launch_description():
pkg_share = os.path.join(
get_package_share_directory('alice4_gazebo'),
'launch'
)

return LaunchDescription([
# Gazebo 시뮬레이션 시작
IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(pkg_share, 'gazebo.launch.py')
)
),

# ALICE4 로봇 스폰
Node(
package='gazebo_ros',
executable='spawn_entity.py',
arguments=[
'-topic', '/robot_description',
'-entity', 'alice4'
],
output='screen'
),

# 조인트 상태 퍼블리셔
Node(
package='joint_state_publisher_gui',
executable='joint_state_publisher_gui',
name='joint_state_publisher_gui',
output='screen'
),

# RViz 시각화
Node(
package='rviz2',
executable='rviz2',
name='rviz2',
arguments=['-d', os.path.join(pkg_share, 'config.rviz')],
output='screen'
)
])

📚 API 레퍼런스

주요 메시지 타입

메시지 타입설명토픽
JointState조인트 각도 및 속도/alice4/joint_states
RobotStatus로봇 상태 정보/alice4/status
JointTrajectory조인트 트래젝토리 명령/alice4/joint_trajectory_controller/joint_trajectory
PoseStamped엔드이펙터 포즈/alice4/ee_pose

서비스 인터페이스

# 캘리브레이션 서비스 호출
from alice4_srvs.srv import Calibrate
import rclpy

client = node.create_client(Calibrate, '/alice4/calibrate')
request = Calibrate.Request()
future = client.call_async(request)
rclpy.spin_until_future_complete(node, future)

🔍 디버깅 및 로깅

로깅 설정

import logging

# ROS2 로깅 레벨 설정
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger('alice4_app')

# ROS2 노드 로깅
node.get_logger().set_level(rclpy.logging.LoggingSeverity.INFO)

오류 처리

try:
# 로봇 제어 코드
mover.move_to_position(target_position)
except Exception as e:
node.get_logger().error(f'Movement failed: {str(e)}')
# 복구 로직
mover.emergency_stop()

프로 팁
  • 복잡한 작업의 경우 MoveIt2 라이브러리를 활용하세요
  • 실시간 성능이 필요한 경우 C++로 구현을 고려하세요
  • 시뮬레이션 환경에서 먼저 테스트한 후 실제 로봇에 적용하세요
다음 단계

이제 ALICE4를 자유자재로 제어할 수 있습니다. 실제 응용 분야에 맞는 고급 튜토리얼을 확인하세요.