- 상과 선 수에 따른 전압강하 계산
- 철손, 동손, 출력이 주어졌을 경우, 변압기 효율
- 역률에 따른 전압 강하



moveit_setup_assistant를 사용하면 대상이 되는 package에서 urdf를 추출한 다음, 필요한 설정 파일을 만든 후 package+moveit_config 디렉토리에 생성한 파일을 저장한다. lanch 디렉토리에 demo.launch.py 파일이 있는데, 코드에는 별 내용은 없고, 같은 디렉토리 launch 파일들을 실행한다. 최소한 어느 부분을 실행해야 rviz에서 로봇이 제대로 보일지 궁금했다
demo.launch.py 파일이 다음을 실행한다.
robot_state_publisher만 실행하면 로봇이 정확하게 보일 줄 알았다. robot_state_publisher가 입력으로 robot_description을 받아들이고, TF는 robot_description에 있는 링크, 조인트 관계만 읽어들여 알아낼 줄 알았다. move_group은 path를 찾을 때 사용하므로 당장 필요해 보이지 않았다.
from launch import LaunchDescription
from moveit_configs_utils import MoveItConfigsBuilder
from launch_ros.actions import Node
from moveit_configs_utils.launches import generate_rsp_launch, generate_moveit_rviz_launch
from launch.actions import (
DeclareLaunchArgument,
IncludeLaunchDescription,
)
from launch.substitutions import LaunchConfiguration
import os
from ament_index_python.packages import get_package_share_directory
from launch.launch_description_sources import PythonLaunchDescriptionSource
def generate_launch_description():
moveit_config = MoveItConfigsBuilder("abb_irb2400", package_name="hello_moveit_config").to_moveit_configs()
#dict2 = moveit_config.to_dict()
#for key, val in (dict2.items()):
# print(key, ":", val)
ld = LaunchDescription()
ld.add_action(DeclareLaunchArgument("publish_frequency", default_value="15.0"))
rsp_node = Node(
name = "rsp_node",
executable = "robot_state_publisher",
#prefix = "xterm -e gdb run --args",
package = "robot_state_publisher",
output = "both",
respawn = True,
#namespace = 'my_robot',
parameters=[
moveit_config.robot_description,
{
"publish_frequency": LaunchConfiguration("publish_frequency"),
},
#moveit_config.robot_description_semantic,
#moveit_config.robot_description_kinematics,
],
)
ld.add_action(rsp_node)
return ld
launch를 실행하면 tf가 제대로 표시되지 않는다. tf_static은 정확하게 표시된다.

root@rygen3600:/home/ros2_test/ws_root/ws_user# ros2 topic list
/attached_collision_object
/clicked_point
/display_planned_path
/goal_pose
/initialpose
/joint_states
/parameter_events
/planning_scene
/planning_scene_world
/recognized_object_array
/robot_description
/rosout
/rviz_moveit_motion_planning_display/robot_interaction_interactive_marker_topic/feedback
/rviz_moveit_motion_planning_display/robot_interaction_interactive_marker_topic/update
/tf
/tf_static
/trajectory_execution_event
/visualization_marker_array
root@rygen3600:/home/ros2_test/ws_root/ws_user# ros2 topic echo /tf
^Croot@rygen3600:/home/ros2_test/ws_root/ws_user# ros2 topic echo /tf_static
transforms:
- header:
stamp:
sec: 1691830604
nanosec: 3856748
frame_id: base_link
child_frame_id: base
transform:
translation:
x: 0.0
y: 0.0
z: 0.0
rotation:
x: 0.0
y: 0.0
z: 0.0
w: 1.0
- header:
stamp:
sec: 1691830604
nanosec: 3856748
frame_id: link_6
child_frame_id: tool0
transform:
translation:
x: 0.0
y: 0.0
z: 0.0
rotation:
x: 0.0
y: 0.0
z: 0.0
w: 1.0
---
왜 이런지 한참 고민하다, 결국 control node와 controller spawner가 실행되어야 TF가 제대로 표시됨을 알았다.

root@rygen3600:/home/ros2_test/ws_root/ws_user# ros2 topic echo /tf
...
- header:
stamp:
sec: 1691830991
nanosec: 709634293
frame_id: base_link
child_frame_id: link_1
transform:
translation:
x: 0.0
y: 0.0
z: 0.0
rotation:
x: 0.0
y: 0.0
z: 0.0
w: 1.0
- header:
stamp:
sec: 1691830991
nanosec: 709634293
frame_id: link_1
child_frame_id: link_2
transform:
translation:
x: 0.1
y: 0.0
z: 0.615
rotation:
x: 0.0
y: 0.0
z: 0.0
w: 1.0
- header:
stamp:
sec: 1691830991
nanosec: 709634293
frame_id: link_2
child_frame_id: link_3
transform:
translation:
x: 0.0
y: 0.0
z: 0.705
rotation:
x: 0.0
y: 0.0
z: 0.0
w: 1.0
최소 2개 node가 필요하다. robot_state_publisher와 controller node.이거 알아낸다고 별 짓을 다했다. 다수 로봇을 처리하려면 namespace로 할당하여 불러야 할텐데, 잘 안된다.

osrf/ros:humble-desktop 도커 이미지를 설치하면 rviz 12.6가 설치된다. 가끔 node를 만들어 robot_description을 입력하면, rviz2가 제대로 표시 안할 경우가 있다. moveit_setup_assistant도 기존 설정 파일을 수정하면 robot_model_loader가 실행되지 않을 경우도 있다. 아마 12.6 버전의 문제인 듯 하여 버전을 올려 보기로 했다. 최신 버전은 12.8인데, humble이 사용할 수 있는 가장 최근 버전은 12.7이다. 12.8을 사용하면 display panel이 안보이는 듯 안정적으로 동작하지 않는다.
now0930@rygen3600:~/ros2/test/ws_root/ws_user$ git clone -b humble https://github.com/ros2/rviz.git 'rviz'에 복제합니다... remote: Enumerating objects: 30445, done. remote: Counting objects: 100% (4756/4756), done. remote: Compressing objects: 100% (1181/1181), done. remote: Total 30445 (delta 3857), reused 4031 (delta 3399), pack-reused 25689 오브젝트를 받는 중: 100% (30445/30445), 16.45 MiB | 16.27 MiB/s, 완료. 델타를 알아내는 중: 100% (22231/22231), 완료. now0930@rygen3600:~/ros2/test/ws_root/ws_user$ cd rviz/ now0930@rygen3600:~/ros2/test/ws_root/ws_user/rviz$ git checkout 브랜치가 'origin/humble'에 맞게 업데이트된 상태입니다.
branch를 선택하지 않고, default 값으로 humble에서 12.8을 컴파일 하고 있었다. 잘 동작되지 않아 2일을 날렸다. work space 구조도 각 패키지에 맞도록 세부적으로 나누어야 한다. 섞이면 컴파일 양도 많고, 각 패키지별로 옵션을 설정할 수 없다. workspace에 대한 내용은 여기에 있다. overlay, underlay를 정확하게 이해하지 않고 가 시간 날렸다.

rviz2 readme를 따라 complie 한다. 컴파일 중 ignition_math6_vendor가 없어 에러로 멈춘다.
CMake Error at CMakeLists.txt:64 (find_package):
By not providing "Findignition_math6_vendor.cmake" in CMAKE_MODULE_PATH
this project has asked CMake to find a package configuration file provided
by "ignition_math6_vendor", but CMake did not find one.
Could not find a package configuration file provided by
"ignition_math6_vendor" with any of the following names:
ignition_math6_vendorConfig.cmake
ignition_math6_vendor-config.cmake
Add the installation prefix of "ignition_math6_vendor" to CMAKE_PREFIX_PATH
or set "ignition_math6_vendor_DIR" to a directory containing one of the
above files. If "ignition_math6_vendor" provides a separate development
package or SDK, be sure it has been installed.
apt-cache로 ros-humble-ignition-math6-vendor를 검색하면, 해당 패키지가 설치되어 있다. dpkg로 어떤 파일들이 있는지 보면, 실재 파일은 없는 듯 하다.
root@rygen3600:/home/ros2_test# dpkg -L ros-humble-ignition-math6-vendor /. /opt /opt/ros /opt/ros/humble /opt/ros/humble/share /opt/ros/humble/share/ignition_math6_vendor /opt/ros/humble/share/ignition_math6_vendor/package.xml /usr /usr/share /usr/share/doc /usr/share/doc/ros-humble-ignition-math6-vendor /usr/share/doc/ros-humble-ignition-math6-vendor/changelog.Debian.gz /usr/share/doc/ros-humble-ignition-math6-vendor/copyright root@rygen3600:/home/ros2_test#
ROS Index를 찾아보면 rviz2 github를 찾을 수 있는데, 이를 rviz에 있는 디렉토리에 받아주면 된다. ignition-math6-vendor가 gz_math6_vendor로 바뀐 느낌이다. CMakefile을 보면 project로 ignition_math6_vendor로 자기를 명명한다.
oot@rygen3600:/home/ros2_test/rviz# ls -alh
total 92K
drwxrwxr-x 17 1000 1000 4.0K Aug 8 21:43 .
drwxrwxr-x 7 1000 1000 4.0K Aug 6 20:45 ..
drwxrwxr-x 8 1000 1000 4.0K Aug 6 20:45 .git
drwxrwxr-x 3 1000 1000 4.0K Aug 6 20:45 .github
-rw-rw-r-- 1 1000 1000 55 Aug 6 20:45 .gitignore
-rw-rw-r-- 1 1000 1000 84 Aug 6 20:45 CODEOWNERS
-rw-rw-r-- 1 1000 1000 1.7K Aug 6 20:45 LICENSE
-rw-rw-r-- 1 1000 1000 8.2K Aug 6 20:45 README.md
drwxr-xr-x 11 root root 4.0K Aug 8 21:49 build
drwxrwxr-x 2 1000 1000 4.0K Aug 6 20:45 docs
drwxrwxr-x 5 1000 1000 4.0K Aug 8 21:43 gz_math6_vendor
drwxr-xr-x 7 root root 4.0K Aug 8 21:49 install
drwxr-xr-x 10 root root 4.0K Aug 8 21:44 log
drwxrwxr-x 6 1000 1000 4.0K Aug 6 20:45 rviz2
drwxrwxr-x 3 1000 1000 4.0K Aug 6 20:45 rviz_assimp_vendor
drwxrwxr-x 8 1000 1000 4.0K Aug 6 20:45 rviz_common
drwxrwxr-x 6 1000 1000 4.0K Aug 8 21:53 rviz_default_plugins
drwxrwxr-x 3 1000 1000 4.0K Aug 6 20:45 rviz_ogre_vendor
drwxrwxr-x 6 1000 1000 4.0K Aug 6 20:45 rviz_rendering
drwxrwxr-x 4 1000 1000 4.0K Aug 6 20:45 rviz_rendering_tests
drwxrwxr-x 7 1000 1000 4.0K Aug 8 20:54 rviz_visual_testing_framework
root@rygen3600:/home/ros2_test/rviz#
root@rygen3600:/home/ros2_test/rviz# cd gz_math6_vendor/
root@rygen3600:/home/ros2_test/rviz/gz_math6_vendor# ls
CHANGELOG.rst CONTRIBUTING.md package.xml
CMakeLists.txt LICENSE patches
root@rygen3600:/home/ros2_test/rviz/gz_math6_vendor# cat CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(ignition_math6_vendor)
find_package(ament_cmake_core REQUIRED)
find_package(ament_cmake_vendor_package REQUIRED)
find_package(ignition-math6 6.9.2 QUIET)
ament_vendor(ignition_math6_vendor
SATISFIED ${ignition-math6_FOUND}
VCS_URL https://github.com/ignitionrobotics/ign-math.git
VCS_VERSION ignition-math6_6.9.2
PATCHES patches
CMAKE_ARGS
-DBUILD_DOCS:BOOL=OFF
GLOBAL_HOOK
)
find_package(ament_cmake_test REQUIRED)
if(BUILD_TESTING)
find_package(ament_cmake_lint_cmake REQUIRED)
find_package(ament_cmake_copyright REQUIRED)
find_package(ament_cmake_xmllint REQUIRED)
ament_lint_cmake()
ament_copyright()
ament_xmllint()
endif()
ament_package()

ros2를 gdb를 사용할 수 있다(대박!). 먼저 ros2 run 옵션으로 사용하는 포스트를 찾았다. 이러면 node를 만들 때 전달한 파라미터를 모두 넣어줘야 하여 어렵고 불편하다. 다행히 ros가 죽을 때 어떤 파일을 사용했는지 알려줬다.
[ERROR] [robot_model_tutorial-1]: process has died [pid 1919, exit code -11, cmd '/home/ros2_test/install/hello_moveit/lib/hello_moveit/robot_model_tutorial --ros-args --params-file /tmp/launch_params_2myb0p1i --params-file /tmp/launch_params_q_86u0o7 --params-file /tmp/launch_params_2dnzqmp1'].
node를 실행할 때, tmp 디렉토리에 파일로 만들어 이를 args로 전달한다. 다음과 같이 ros run으로 gdb를 붙일 수 있다.
ros2 run --prefix 'gdb -ex run --args' hello_moveit robot_model_tutorial --ros-args --params-file /tmp/launch_params_2myb0p1i --params-file /tmp/launch_params_q_86u0o7 --params-file /tmp/launch_params_2dnzqmp1
파라미터 입력이 귀찮으면, launch 옵션에 prefix로 넣어 사용할 수 있다. 단 터미널을 새로 만들어야 한다. 왜 그런지는 잘 모르겠는데, 일단 되니까 패스.
from launch import LaunchDescription
from launch_ros.actions import Node
from moveit_configs_utils import MoveItConfigsBuilder
def generate_launch_description():
moveit_config = MoveItConfigsBuilder("hello").to_moveit_configs()
my_node = Node(
package="hello_moveit",
executable="robot_model_tutorial",
output="screen",
parameters=[
moveit_config.robot_description,
moveit_config.robot_description_semantic,
moveit_config.robot_description_kinematics,
],
)
return LaunchDescription([my_node])
from launch import LaunchDescription
from launch_ros.actions import Node
from moveit_configs_utils import MoveItConfigsBuilder
def generate_launch_description():
moveit_config = MoveItConfigsBuilder("hello").to_moveit_configs()
my_node = Node(
package="hello_moveit",
executable="robot_model_tutorial",
prefix ="xterm -e gdb run --args",
output="screen",
parameters=[
moveit_config.robot_description,
moveit_config.robot_description_semantic,
moveit_config.robot_description_kinematics,
],
)
return LaunchDescription([my_node])
gdb 기본 사용법은 여기 정리되어 있다.