head actPolicy rviz - dingdongdengdong/astra_ws GitHub Wiki

๋กœ๋ด‡ ํ—ค๋“œ ์ œ์–ด ๊ตฌํ˜„ + LeRobot ACT Policy ํœด๋จธ๋…ธ์ด๋“œ ๋กœ๋ด‡ ํŒ” ๋™์ž‘ RViz ์‹œ๊ฐํ™” ํ…Œ์ŠคํŠธ

๋กœ๋ด‡ ํ—ค๋“œ ์ œ์–ด ๋ถ€

ํ•ต์‹ฌ ๊ตฌ์„ฑ ์š”์†Œ:

  1. head_controller.py: ์‹ค์ œ ๋กœ๋ด‡ ํ—ค๋“œ ํ•˜๋“œ์›จ์–ด(๋ชจํ„ฐ)์™€ ์ง์ ‘ ํ†ต์‹ ํ•˜๊ณ  ์ œ์–ดํ•˜๋Š” ์ €์ˆ˜์ค€ ์ปจํŠธ๋กค๋Ÿฌ์ž…๋‹ˆ๋‹ค. ์‹œ๋ฆฌ์–ผ ํ†ต์‹ ์„ ํ†ตํ•ด ๋ช…๋ น์„ ์ „๋‹ฌํ•˜๊ณ , ์—”์ฝ”๋” ๊ฐ’ ๋“ฑ์„ ์ฝ์–ด์˜ต๋‹ˆ๋‹ค.
  2. head_node.py: ROS2 ๋…ธ๋“œ๋กœ์„œ, head_controller.py์™€ ROS2 ์‹œ์Šคํ…œ ๊ฐ„์˜ ์ธํ„ฐํŽ˜์ด์Šค ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ROS2 ๋…ธ๋“œ๋กœ๋ถ€ํ„ฐ ์ œ์–ด ๋ช…๋ น์„ ๋ฐ›์•„ head_controller.py์— ์ „๋‹ฌํ•˜๊ณ , head_controller.py๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ ํ—ค๋“œ์˜ ์ƒํƒœ ์ •๋ณด๋ฅผ /joint_states ํ† ํ”ฝ์œผ๋กœ ๋ฐœํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  3. URDF (Unified Robot Description Format): ๋กœ๋ด‡์˜ ๋ฌผ๋ฆฌ์ ์ธ ๊ตฌ์กฐ(๋งํฌ, ์กฐ์ธํŠธ, ์™ธํ˜• ๋“ฑ)๋ฅผ XML ํ˜•์‹์œผ๋กœ ๊ธฐ์ˆ ํ•œ ํŒŒ์ผ์ž…๋‹ˆ๋‹ค. RViz2๋‚˜ Gazebo์™€ ๊ฐ™์€ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ ๋ฐ ์‹œ๊ฐํ™” ๋„๊ตฌ์—์„œ ๋กœ๋ด‡ ๋ชจ๋ธ์„ ํ‘œ์‹œํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. (astra_description ํŒจํ‚ค์ง€์— ๊ด€๋ จ ํŒŒ์ผ์ด ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.)
  4. robot_state_publisher: URDF ํŒŒ์ผ๊ณผ /joint_states ํ† ํ”ฝ์„ ์ž…๋ ฅ์œผ๋กœ ๋ฐ›์•„, ๊ฐ ์กฐ์ธํŠธ์˜ ํ˜„์žฌ ์ƒํƒœ์— ๋”ฐ๋ฅธ ๋กœ๋ด‡ ๊ฐ ๋ถ€๋ถ„์˜ 3D ์ขŒํ‘œ ๋ณ€ํ™˜ ์ •๋ณด(TF, Transform)๋ฅผ ๋ฐœํ–‰ํ•˜๋Š” ROS2 ๋…ธ๋“œ์ž…๋‹ˆ๋‹ค.
  5. RViz2: ROS2์—์„œ ์‚ฌ์šฉ๋˜๋Š” 3D ์‹œ๊ฐํ™” ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. TF ์ •๋ณด์™€ ๋กœ๋ด‡ ๋ชจ๋ธ(URDF)์„ ์‚ฌ์šฉํ•˜์—ฌ ๋กœ๋ด‡์˜ ํ˜„์žฌ ์ž์„ธ๋ฅผ ์‹œ๊ฐ์ ์œผ๋กœ ๋ณด์—ฌ์ฃผ๊ณ , ๋‹ค์–‘ํ•œ ์„ผ์„œ ๋ฐ์ดํ„ฐ(์นด๋ฉ”๋ผ, ๋ผ์ด๋‹ค ๋“ฑ)๋ฅผ ํ•จ๊ป˜ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ตฌํ˜„ ๋ฐ ์‹คํ–‰ ํ๋ฆ„ ๋‹ค์ด์–ด๊ทธ๋žจ:

graph TD
    %% Define overall graph direction
    direction TB

    %% Subgraph for ROS2 Control Stack
    subgraph "ROS2 Control Stack"
        direction LR
        A["External Control\n(Teleop/MoveIt)"] -->|"JointCommand"| B[head_node.py]
        B -->|"Set Position/Torque"| C[head_controller.py]
        C -->|"Joint States (Raw)"| B
        B -->|"/joint_states\n(sensor_msgs/JointState)"| D[robot_state_publisher]
        E["URDF\n(astra_description)"] --> D
        D -->|"/tf\n(tf2_msgs/TFMessage)"| F[RViz2]
        E --> F
    end

    %% Subgraph for Hardware Interaction
    subgraph "Physical/Simulated Hardware"
        direction LR
        C <-->|"Motor Control/Feedback"| G["Robot Head\n(Motors/Encoders)"]
    end

    %% Subgraph for Visualization
    subgraph "Visualization"
        direction LR
        F -->|"Displays Robot Model"| H[User Interface]
    end

    %% Styling for visual clarity
    classDef rosNode fill:#D6EAF8,stroke:#2E86C1,stroke-width:2px
    classDef hardware fill:#FDEDEC,stroke:#CB4335,stroke-width:2px
    classDef viz fill:#D5F5E3,stroke:#28B463,stroke-width:2px
    classDef config fill:#E5E7E9,stroke:#566573,stroke-width:2px

    class A,B,C,D rosNode
    class G hardware
    class F,H viz
    class E config

ํ๋ฆ„ ์„ค๋ช…:

  1. ๋ช…๋ น ๋ฐœ์ƒ (A -> B):

    • ์‚ฌ์šฉ์ž ์ž…๋ ฅ(ํ‚ค๋ณด๋“œ, ์กฐ์ด์Šคํ‹ฑ ๋“ฑ)์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์›๊ฒฉ ์กฐ์ž‘ ๋…ธ๋“œ(teleop_node.py ๋“ฑ)๋‚˜, ๋ณต์žกํ•œ ๊ฒฝ๋กœ ๊ณ„ํš์„ ์ˆ˜ํ–‰ํ•˜๋Š” MoveIt!๊ณผ ๊ฐ™์€ ์ƒ์œ„ ๋ ˆ๋ฒจ์˜ ์ œ์–ด ๋…ธ๋“œ(A)๊ฐ€ ๋กœ๋ด‡ ํ—ค๋“œ์˜ ๋ชฉํ‘œ ๊ด€์ ˆ ์œ„์น˜๋ฅผ ๋‹ด์€ astra_controller_interfaces.msg.JointCommand ๋ฉ”์‹œ์ง€๋ฅผ /joint_command ํ† ํ”ฝ์œผ๋กœ ๋ฐœํ–‰ํ•ฉ๋‹ˆ๋‹ค.
    • (๋˜๋Š” ํ† ํฌ ํ™œ์„ฑํ™”/๋น„ํ™œ์„ฑํ™”๋ฅผ ์œ„ํ•œ std_msgs.msg.UInt8 ๋ฉ”์‹œ์ง€๊ฐ€ /torque_enable ํ† ํ”ฝ์œผ๋กœ ๋ฐœํ–‰๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.)
  2. ROS2 ๋…ธ๋“œ์—์„œ์˜ ๋ช…๋ น ์ฒ˜๋ฆฌ (B -> C):

    • head_node.py(B)๋Š” /joint_command ํ† ํ”ฝ์„ ๊ตฌ๋…ํ•˜๊ณ  ์žˆ๋‹ค๊ฐ€ ์ƒˆ๋กœ์šด ๋ช…๋ น ๋ฉ”์‹œ์ง€๋ฅผ ์ˆ˜์‹ ํ•ฉ๋‹ˆ๋‹ค.
    • ์ˆ˜์‹ ๋œ ๋ฉ”์‹œ์ง€๋กœ๋ถ€ํ„ฐ ๋ชฉํ‘œ ๊ด€์ ˆ ์œ„์น˜ ๊ฐ’(pan, tilt ๊ฐ๋„)์„ ์ถ”์ถœํ•ฉ๋‹ˆ๋‹ค.
    • HeadController ํด๋ž˜์Šค์˜ set_pos() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ head_controller.py(C)์— ๋ชฉํ‘œ ์œ„์น˜๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
    • ๋งŒ์•ฝ /torque_enable ํ† ํ”ฝ์œผ๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ›์œผ๋ฉด, HeadController์˜ set_torque() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
  3. ํ•˜๋“œ์›จ์–ด ์ œ์–ด (C <-> G):

    • head_controller.py(C)๋Š” set_pos() ๋˜๋Š” set_torque() ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด, ํ•ด๋‹น ๋ช…๋ น์„ ๋กœ๋ด‡ ํ—ค๋“œ ๋ชจํ„ฐ(G)๊ฐ€ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋Š” ์‹œ๋ฆฌ์–ผ ํ”„๋กœํ† ์ฝœ ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
    • ๋ณ€ํ™˜๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์‹œ๋ฆฌ์–ผ ํฌํŠธ๋ฅผ ํ†ตํ•ด ์‹ค์ œ ๋กœ๋ด‡ ํ—ค๋“œ ๋ชจํ„ฐ ์ปจํŠธ๋กค๋Ÿฌ์— ์ „์†กํ•ฉ๋‹ˆ๋‹ค.
    • ๋™์‹œ์—, recv_thread๋Š” ํ—ค๋“œ ๋ชจํ„ฐ ์ปจํŠธ๋กค๋Ÿฌ๋กœ๋ถ€ํ„ฐ ํ˜„์žฌ ์—”์ฝ”๋” ๊ฐ’(raw data)๊ณผ ๊ฐ™์€ ํ”ผ๋“œ๋ฐฑ ๋ฐ์ดํ„ฐ๋ฅผ ์ง€์†์ ์œผ๋กœ ์ˆ˜์‹ ํ•ฉ๋‹ˆ๋‹ค.
  4. ์ƒํƒœ ํ”ผ๋“œ๋ฐฑ (C -> B):

    • head_controller.py(C)๋Š” ์ˆ˜์‹ ๋œ raw ์—”์ฝ”๋” ๊ฐ’์„ SI ๋‹จ์œ„(๋ผ๋””์•ˆ)๋กœ ๋ณ€ํ™˜ํ•˜๊ณ , ์ด๋ฅผ ์ด์šฉํ•ด ํ˜„์žฌ ๊ด€์ ˆ ์œ„์น˜, ์†๋„, ์ถ”์ • ํ† ํฌ๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.
    • ์ด ๊ณ„์‚ฐ๋œ ์ƒํƒœ ์ •๋ณด๋Š” head_node.py(B)์— ๋“ฑ๋ก๋œ state_cb ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค.
  5. ์กฐ์ธํŠธ ์ƒํƒœ ๋ฐœํ–‰ (B -> D):

    • head_node.py(B)์˜ state_cb ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋Š” head_controller.py๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ ํ˜„์žฌ ๊ด€์ ˆ ์ƒํƒœ(์œ„์น˜, ์†๋„, ์ถ”์ • ํ† ํฌ)๋ฅผ sensor_msgs.msg.JointState ๋ฉ”์‹œ์ง€ ํ˜•์‹์œผ๋กœ ์ฑ„์›๋‹ˆ๋‹ค.
    • ์ด JointState ๋ฉ”์‹œ์ง€๋ฅผ /joint_states ํ† ํ”ฝ์œผ๋กœ ๋ฐœํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ด ํ† ํ”ฝ์—๋Š” ๋กœ๋ด‡์˜ ๋ชจ๋“  ์กฐ์ธํŠธ("joint_head_pan", "joint_head_tilt")์˜ ํ˜„์žฌ ์ƒํƒœ๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.
  6. TF ์ •๋ณด ๋ฐœํ–‰ (D -> F):

    • robot_state_publisher ๋…ธ๋“œ(D)๋Š” ๋กœ๋ด‡์˜ URDF ๋ชจ๋ธ(astra_description ํŒจํ‚ค์ง€ ๋‚ด)๊ณผ /joint_states ํ† ํ”ฝ์„ ๊ตฌ๋…ํ•ฉ๋‹ˆ๋‹ค.
    • /joint_states ํ† ํ”ฝ์œผ๋กœ๋ถ€ํ„ฐ ๊ฐ ์กฐ์ธํŠธ์˜ ํ˜„์žฌ ๊ฐ๋„ ๊ฐ’์„ ๋ฐ›์œผ๋ฉด, URDF์— ์ •์˜๋œ ๋กœ๋ด‡์˜ ๊ฐ ๋งํฌ(link)๋“ค ์‚ฌ์ด์˜ ์ƒ๋Œ€์ ์ธ 3D ๊ณต๊ฐ„ ๋ณ€ํ™˜ ๊ด€๊ณ„(TF)๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.
    • ๊ณ„์‚ฐ๋œ TF ์ •๋ณด๋Š” /tf ํ† ํ”ฝ์œผ๋กœ ๋ฐœํ–‰๋ฉ๋‹ˆ๋‹ค. ์ด ์ •๋ณด๋Š” ๋กœ๋ด‡์˜ ๊ฐ ๋ถ€๋ถ„์ด ํ˜„์žฌ ์–ด๋–ค ์ž์„ธ๋กœ ์œ„์น˜ํ•ด ์žˆ๋Š”์ง€๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
  7. RViz2์—์„œ์˜ ์‹œ๊ฐํ™” (E, F -> H):

    • RViz2(F)๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์„ค์ •ํ•œ ๋‚ด์šฉ์— ๋”ฐ๋ผ ๋‹ค์–‘ํ•œ ํ† ํ”ฝ์„ ์‹œ๊ฐํ™”ํ•ฉ๋‹ˆ๋‹ค.
    • RobotModel Display: URDF(E)๋ฅผ ๋กœ๋“œํ•˜๊ณ , /tf ํ† ํ”ฝ(D๋กœ๋ถ€ํ„ฐ ๋ฐœํ–‰๋จ)์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ ๋งํฌ๋ฅผ ์˜ฌ๋ฐ”๋ฅธ ์œ„์น˜์™€ ์ž์„ธ๋กœ 3D ๊ณต๊ฐ„์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž๋Š” ๋กœ๋ด‡ ํ—ค๋“œ๊ฐ€ ์‹ค์ œ๋กœ ์–ด๋–ป๊ฒŒ ์›€์ง์ด๋Š”์ง€ ํ™”๋ฉด(H)์„ ํ†ตํ•ด ์‹ค์‹œ๊ฐ„์œผ๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • TF Display: /tf ์ •๋ณด๋ฅผ ์ง์ ‘ ์‹œ๊ฐํ™”ํ•˜์—ฌ ๊ฐ ์ขŒํ‘œ๊ณ„(frame)๋“ค์ด ์–ด๋–ป๊ฒŒ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๊ณ  ์›€์ง์ด๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • (ํ•„์š”์— ๋”ฐ๋ผ Grid, Camera Image ๋“ฑ ๋‹ค๋ฅธ Display ํƒ€์ž…๋„ ์ถ”๊ฐ€ํ•˜์—ฌ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.)

์‹คํ–‰ ๋‹จ๊ณ„ (ํ„ฐ๋ฏธ๋„ ๋ช…๋ น์–ด ์˜ˆ์‹œ):

์‹ค์ œ ๋กœ๋ด‡ ํ•˜๋“œ์›จ์–ด๋ฅผ ์—ฐ๊ฒฐํ•œ ๊ฒฝ์šฐ์™€ ์‹œ๋ฎฌ๋ ˆ์ด์…˜๋งŒ ํ•˜๋Š” ๊ฒฝ์šฐ์— ๋”ฐ๋ผ ๋‹จ๊ณ„๊ฐ€ ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” ์ œ๊ณต๋œ ์ฝ”๋“œ๊ฐ€ ์‹ค์ œ ํ•˜๋“œ์›จ์–ด ์ œ์–ด๋ฅผ ๋ชฉํ‘œ๋กœ ํ•˜๋ฏ€๋กœ, ์‹ค์ œ ํ•˜๋“œ์›จ์–ด ์—ฐ๊ฒฐ์„ ๊ฐ€์ •ํ•˜๊ณ  RViz2์—์„œ ์‹œ๊ฐํ™”ํ•˜๋Š” ๋‹จ๊ณ„๋ฅผ ์ค‘์‹ฌ์œผ๋กœ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

  1. ROS2 ํ™˜๊ฒฝ ์„ค์ •:

    source /opt/ros/<your_ros_distro>/setup.bash
    source <path_to_your_astra_ws>/install/setup.bash
    
  2. head_controller์™€ ํ†ต์‹ ํ•  ํ•˜๋“œ์›จ์–ด ์—ฐ๊ฒฐ ๋ฐ ๊ถŒํ•œ ํ™•์ธ:

    • ๋กœ๋ด‡ ํ—ค๋“œ ์ปจํŠธ๋กค ๋ณด๋“œ๊ฐ€ PC์™€ ์‹œ๋ฆฌ์–ผ๋กœ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๊ณ , head_node.py์— ์ง€์ •๋œ ์žฅ์น˜ ๊ฒฝ๋กœ(device ํŒŒ๋ผ๋ฏธํ„ฐ, ์˜ˆ: /dev/tty_head)๊ฐ€ ์˜ฌ๋ฐ”๋ฅธ์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
    • ํ•„์š”์‹œ ํ•ด๋‹น ์žฅ์น˜์— ์ ‘๊ทผ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•ฉ๋‹ˆ๋‹ค (sudo chmod 666 /dev/tty_head ๋“ฑ).
  3. head_node ์‹คํ–‰:

    • head_node.py๋Š” head_controller.py๋ฅผ ๋‚ด๋ถ€์ ์œผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
    • ๋ณดํ†ต ROS2 launch ํŒŒ์ผ์„ ํ†ตํ•ด ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. astra_controller ํŒจํ‚ค์ง€ ๋‚ด์— head_node๋ฅผ ์‹คํ–‰ํ•˜๋Š” launch ํŒŒ์ผ์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ฑฐ๋‚˜, ์ง์ ‘ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ๋งŒ์•ฝ launch ํŒŒ์ผ์ด ์žˆ๋‹ค๋ฉด (์˜ˆ: astra_controller/launch/head.launch.py):
      ros2 launch astra_controller head.launch.py
      
    • ์ง์ ‘ ์‹คํ–‰ํ•œ๋‹ค๋ฉด (ํŒŒ๋ผ๋ฏธํ„ฐ ์„ค์ • ํ•„์š”):
      ros2 run astra_controller head_node --ros-args -p device:=/dev/tty_head
      
    • ์ด ๋…ธ๋“œ๊ฐ€ ์‹คํ–‰๋˜๋ฉด /joint_states ํ† ํ”ฝ์ด ๋ฐœํ–‰๋˜๊ธฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.
  4. robot_state_publisher ์‹คํ–‰:

    • ๋กœ๋ด‡์˜ URDF ํŒŒ์ผ์„ ๋กœ๋“œํ•˜๊ณ  /joint_states๋ฅผ ๋ฐ›์•„ TF๋ฅผ ๋ฐœํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋˜ํ•œ launch ํŒŒ์ผ๋กœ ๊ด€๋ฆฌ๋˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ž…๋‹ˆ๋‹ค. astra_description ๋˜๋Š” astra_moveit_config ๊ฐ™์€ ํŒจํ‚ค์ง€์— rsp.launch.py (Robot State Publisher์˜ ์•ฝ์ž) ๋˜๋Š” ์œ ์‚ฌํ•œ ์ด๋ฆ„์˜ launch ํŒŒ์ผ์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ์˜ˆ์‹œ (์‹ค์ œ ํŒŒ์ผ๋ช…์€ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Œ):
      ros2 launch astra_description robot_state_publisher.launch.py
      
      ๋˜๋Š” astra_moveit_config์— ํฌํ•จ๋œ rsp.launch.py๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
      ros2 launch astra_moveit_config rsp.launch.py
      
  5. RViz2 ์‹คํ–‰:

    • ์ƒˆ ํ„ฐ๋ฏธ๋„์„ ์—ด๊ณ  RViz2๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
      rviz2
      
    • RViz2๊ฐ€ ์‹คํ–‰๋˜๋ฉด ๋‹ค์Œ ์„ค์ •์„ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค:
      • Global Options: Fixed Frame์„ ๋กœ๋ด‡์˜ base_link (๋˜๋Š” odom ๋“ฑ ๊ธฐ์ค€์ด ๋˜๋Š” ํ”„๋ ˆ์ž„)๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. URDF์— ์ •์˜๋œ ํ”„๋ ˆ์ž„ ์ด๋ฆ„์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
      • Add Display: ์™ผ์ชฝ ํ•˜๋‹จ์˜ "Add" ๋ฒ„ํŠผ์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.
        • By display type ํƒญ์—์„œ RobotModel์„ ์„ ํƒํ•˜๊ณ  OK๋ฅผ ๋ˆ„๋ฆ…๋‹ˆ๋‹ค.
          • Description Source๊ฐ€ Topic์œผ๋กœ ๋˜์–ด์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ , Description Topic์ด /robot_description (๋˜๋Š” robot_state_publisher๊ฐ€ ๋ฐœํ–‰ํ•˜๋Š” ๋กœ๋ด‡ ๋ชจ๋ธ ํ† ํ”ฝ๋ช…)์œผ๋กœ ์„ค์ •๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
          • TF Prefix๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๋น„์›Œ๋‘ก๋‹ˆ๋‹ค.
        • By display type ํƒญ์—์„œ TF๋ฅผ ์„ ํƒํ•˜๊ณ  OK๋ฅผ ๋ˆ„๋ฆ…๋‹ˆ๋‹ค (์„ ํƒ ์‚ฌํ•ญ, TF ์‹œ๊ฐํ™”).
          • Show Names, Show Axes, Show Arrows ๋“ฑ์„ ์ทจํ–ฅ์— ๋งž๊ฒŒ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
  6. (์„ ํƒ ์‚ฌํ•ญ) ํ—ค๋“œ ์ œ์–ด ๋ช…๋ น ๋ฐœํ–‰ ๋…ธ๋“œ ์‹คํ–‰:

    • ํ—ค๋“œ๋ฅผ ์‹ค์ œ๋กœ ์›€์ง์—ฌ๋ณด๋ ค๋ฉด ์ œ์–ด ๋ช…๋ น์„ ๋ฐœํ–‰ํ•˜๋Š” ๋…ธ๋“œ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
    • ๊ฐ„๋‹จํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด ros2 topic pub ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜, ์ œ๊ณต๋œ teleop_node.py ๋˜๋Š” ๋‹ค๋ฅธ ์ œ์–ด ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ์˜ˆ์‹œ (ros2 topic pub ์‚ฌ์šฉ - pan 0.5 ๋ผ๋””์•ˆ, tilt 0.2 ๋ผ๋””์•ˆ์œผ๋กœ ์ด๋™):
      ros2 topic pub --once /joint_command astra_controller_interfaces/msg/JointCommand '{name: ["joint_head_pan", "joint_head_tilt"], position_cmd: [0.5, 0.2]}'
      
    • teleop_node.py๊ฐ€ ์žˆ๋‹ค๋ฉด:
      ros2 run astra_controller teleop_node
      
      (์‹คํ–‰ ๋ฐฉ๋ฒ•์€ ํ•ด๋‹น ๋…ธ๋“œ์˜ ๊ตฌํ˜„์— ๋”ฐ๋ผ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.)

์ฃผ์˜์‚ฌํ•ญ:

  • URDF ๊ฒฝ๋กœ ๋ฐ ๋‚ด์šฉ: robot_state_publisher๊ฐ€ ์˜ฌ๋ฐ”๋ฅธ URDF ํŒŒ์ผ์„ ์ฐธ์กฐํ•˜๋„๋ก ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. URDF ํŒŒ์ผ ๋‚ด์˜ ์กฐ์ธํŠธ ์ด๋ฆ„(joint_head_pan, joint_head_tilt)์€ head_node.py์—์„œ /joint_states๋กœ ๋ฐœํ–‰ํ•˜๋Š” ์กฐ์ธํŠธ ์ด๋ฆ„๊ณผ ์ •ํ™•ํžˆ ์ผ์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • Launch ํŒŒ์ผ ํ™œ์šฉ: ์ผ๋ฐ˜์ ์œผ๋กœ ์œ„์—์„œ ์–ธ๊ธ‰๋œ ๋…ธ๋“œ๋“ค์€ ๊ฐœ๋ณ„์ ์œผ๋กœ ์‹คํ–‰ํ•˜๊ธฐ๋ณด๋‹ค๋Š”, ํ•˜๋‚˜์˜ ํ†ตํ•ฉ๋œ launch ํŒŒ์ผ์„ ํ†ตํ•ด ํ•จ๊ป˜ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. astra_ws/src/astra_controller/launch/start.launch.py ์™€ ๊ฐ™์€ ํŒŒ์ผ์ด ์ „์ฒด ์‹œ์Šคํ…œ์„ ์‹คํ–‰ํ•˜๋Š” ์—ญํ• ์„ ํ•  ์ˆ˜ ์žˆ์œผ๋‹ˆ ํ™•์ธํ•ด๋ณด์‹œ๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ํŠนํžˆ demo.launch.py๋‚˜ moveit_rviz.launch.py ๊ฐ™์€ ํŒŒ์ผ์€ RViz2์™€ ํ•จ๊ป˜ ํ•„์š”ํ•œ ๋ชจ๋“  ๊ฒƒ์„ ์‹คํ–‰ํ•˜๋„๋ก ๊ตฌ์„ฑ๋˜์–ด ์žˆ์„ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์Šต๋‹ˆ๋‹ค.
  • ์‹œ๋ฎฌ๋ ˆ์ด์…˜ (Gazebo ๋“ฑ): ๋งŒ์•ฝ ์‹ค์ œ ํ•˜๋“œ์›จ์–ด ์—†์ด Gazebo์™€ ๊ฐ™์€ ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ์—์„œ ๋กœ๋ด‡์„ ๊ตฌ๋™ํ•˜๋ ค๋ฉด, ros2_control๊ณผ Gazebo ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์„ค์ •ํ•˜์—ฌ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ ํ™˜๊ฒฝ ๋‚ด์—์„œ /joint_states๋ฅผ ๋ฐœํ–‰ํ•˜๊ณ  /joint_command๋ฅผ ๋ฐ›์•„ ๋ชจํ„ฐ๋ฅผ ์›€์ง์ด๋„๋ก ๊ตฌ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋ณ„๋„์˜ ์„ค์ •๊ณผ launch ํŒŒ์ผ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ œ๊ณต๋œ ์ฝ”๋“œ์—๋Š” ros2_control ๊ด€๋ จ ์„ค์ •์ด astra_moveit_config/config/ros2_controllers.yaml ๋“ฑ์— ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ์„ค๋ช…์„ ๋ฐ”ํƒ•์œผ๋กœ ์ œ๊ณต๋œ ์ฝ”๋“œ๋ฅผ ๋นŒ๋“œํ•˜๊ณ  ์‹คํ–‰ํ•˜์—ฌ RViz2์—์„œ ๋กœ๋ด‡ ํ—ค๋“œ๊ฐ€ ์ œ์–ด๋˜๋Š” ๋ชจ์Šต์„ ํ™•์ธํ•˜์‹ค ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ฐ ํŒจํ‚ค์ง€์˜ launch ํด๋”์™€ config ํด๋”๋ฅผ ์ž์„ธํžˆ ์‚ดํŽด๋ณด์‹œ๋ฉด ์‹ค์ œ ์‹คํ–‰์— ํ•„์š”ํ•œ ๊ตฌ์ฒด์ ์ธ ํŒŒ์ผ๋“ค๊ณผ ์„ค์ •์„ ์ฐพ์œผ์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

actpolicy with rviz