Let’s go!

  • Euler transform과 quarternion

    여러 사이트를 돌아 다니다 발견한 개념 동영상. 이거 보면 한 번에 이해 된다.

    • Euler transform 으로 key frame 사이 보간을 제대로 할 수 없다.
    • x축 회전 -> y축 회전 -> z축 회전 상태와 y축 회전 -> x축 회전 -> z축 회전 상태가 다르다.
    • quarternion은 key frame 사이 보간을 제대로 표현할 수 있다.
    • Euler transform은 x, y, z 축으로 회전할 수 있다.
    • quarternion은 임의 축 u로 회전할 수 있다.

    22-9-17 업데이트

    여기 사이트가 복소수와 쿼터니언이 어떻게 같은지 한눈에 보여준다.

  • urdf 작성하여 rviz로 표시하기

    urdf 작성하여 rviz로 표시하기

    tutorial site를 참조하여 실습을 했다. 로봇 살 돈이 없어 몸으로 때우는 수 밖에. 요즘 원자재와 공급망 이슈로 값도 오르고 구하기도 힘들다. 막상 사 보면 그렇게 자주 쓰이지도 않아 보인다.

    https://www.notion.so/2-2-1-URDF-930e055d01ee49cd859ac02ea8770325

    http://wiki.ros.org/urdf/Tutorials/Building%20a%20Visual%20Robot%20Model%20with%20URDF%20from%20Scratch

    3차원 그래픽을 직접 수정하여 각 좌표를 찾으면 쉬운데, URDF 형식이 지원하지 않는다. 각 부품이 어디에 붙는지 계산하여 직접 입력해야 한다.

    urdf를 수정 한 후 rviz로 보면 No transform from A to B 메세지가 나오면서 link가 표시되지 않는다. 다음 순서대로 실행하면 된다.

    1. tutorial 참조하여 launch 파일 작성. robot_state_publisher와 joint_state_publisher를 launch에 넣어야 한다.
    2. roslaunch로 launch 실행
    3. rviz 실행
    <launch>
        <param name="robot_description" command="$(find xacro)/xacro $(find robot)/urdf/robot.urdf" />
    <node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher"/>
    <node pkg="joint_state_publisher_gui" type="joint_state_publisher_gui" name="joint_state_publisher_gui"/>
    
    </launch>
    

    rviz를 한버만 실행하고 launch 하면 no transform 메세지를 본다. urdf 파일 만들 때 각 수치를 정확하게 알 수 없어 귀찮아서 rviz를 한 번 켜놓고 끄질 않는데, 이 때문에 안 보인다. gui툴로 표시된 슬라이더를 돌리면 좌표가 회전됨을 확인 할 수 있다.

    능력자는 잘 만들겠지만, 내 수준에서는 바퀴 두 개도 겨우 따라 했다. material은 rgb 코드를 255로 나눠줘야 한다.

    <?xml version="1.0" ?>
    <robot name="mobile_robot" xmlns:xacro="http://www.ros.org/wiki/xacro">
    	<material name="blue">
    		<color rgba = "0 0 0.8 1"/>
    	</material>
    
    	<material name="gray">
    		<color rgba = "1 1 1 1"/>
    	</material>
    
    	<material name="blueviolet">
    		<color rgba = "0.54 0.16 0.88 1"/>
    	</material>
    	<link name = "base_footprint"/>
    	<link name="base_link">
    		<visual>
    			<origin xyz="0 0 0" rpy = "0 0 0"/>
    			<geometry>
    				<box size = "0.3 0.24 0.1" rpy = "0 0 0" />
    			</geometry>
    			<material name = "gray"/>
    
    		</visual>
    		<collision>
    			<origin xyz="0 0 0.03" rpy = "0 0 0"/>
    			<geometry>
    				<box size = "0.3 0.25 0.1" />
    			</geometry>
    
    		</collision>
    	</link>
    	<joint name = "base_footprint_fixed" type = "fixed">
    		<origin xyz = "0 0 0.03" rpy = "0 0 0"/>
    		<parent link = "base_footprint"/>
    		<child link = "base_link"/>
    	</joint>
    
    
    	<link name = "left_wheel">
    		<visual>
    			<origin xyz = "0 0 0" rpy = "1.570796 0 0" />
    			<geometry>
    				<cylinder length = "0.05" radius = "0.08" />
    			</geometry>
    			<material name ="blue"/>
    
    		</visual>
    		<collision>
    			<origin xyz = "0 0 0" rpy = "1.570796 0 0" />
    			<geometry>
    				<cylinder length = "0.05" radius = "0.08" />
    			</geometry>
    
    		</collision>
    
    	</link>
    
    	<link name = "right_wheel">
    		<visual>
    			<origin xyz = "0 0 0" rpy = "1.570796 0 0" />
    			<geometry>
    				<cylinder length = "0.05" radius = "0.08" />
    			</geometry>
    			<material name ="blue"/>
    
    		</visual>
    		<collision>
    			<origin xyz = "0 0 0" rpy = "1.570796 0 0" />
    			<geometry>
    				<cylinder length = "0.05" radius = "0.08" />
    			</geometry>
    
    		</collision>
    
    	</link>
    
    
    	<joint name = "left_wheel_joint" type = "continuous">
    		<origin xyz = "0.1 0.15 0" rpy = "0 0 0"/>
    		<parent link = "base_link"/>
    		<child link = "left_wheel"/>
    		<axis xyz = "0 1 0"/>
    
    	</joint>
    
    	<joint name = "right_wheel_joint" type = "continuous">
    		<origin xyz = "0.1 -0.15 0" rpy = "0 0 0"/>
    		<parent link = "base_link"/>
    		<child link = "right_wheel"/>
    		<axis xyz = "0 1 0" />
    
    	</joint>
    
    	<link name="scanner_link">
    		<visual>
    			<origin xyz="0 0 0" rpy = "0 0 0"/>
    			<geometry>
    				<cylinder length="0.05" radius="0.035"/>
    			</geometry>
    			<material name = "blueviolet"/>
    
    		</visual>
    		<collision>
    			<origin xyz="0 0 0" rpy = "0 0 0"/>
    			<geometry>
    				<cylinder length="0.05" radius="0.035"/>
    			</geometry>
    
    		</collision>
    	</link>
    
    	<joint name = "head_scanner" type = "fixed">
    		<origin xyz = "0.15 0 0" rpy = "0 1.5708 0"/>
    		<parent link = "base_link"/>
    		<child link = "scanner_link"/>
    	</joint>
    </robot>
  • ros를 nvidia docker로 돌리기

    ros를 nvidia docker로 돌리기

    최신 ros docker 이미지로 gazebo를 그냥 돌리면 초당 4 frame으로 업데이트 된다. 참고 사용 사용하려다 느려 도저히 사용할 수 없어 방법을 찾아 봤다. nvidia-docker로 runtime을 nvidia로 입력해 주면 초 당 60 프레임으로 업데이트 된다. 금방 할 수 있어 찾은 보람이 있다.

    http://wiki.ros.org/docker/Tutorials/Hardware%20Acceleration

    위 사이트를 참조하여 아래 Dockerfile로 새롭게 이미지를 만들었다.

    FROM osrf/ros:noetic-desktop-full
    
    # nvidia-container-runtime
    ENV NVIDIA_VISIBLE_DEVICES \
        ${NVIDIA_VISIBLE_DEVICES:-all}
    ENV NVIDIA_DRIVER_CAPABILITIES \
        ${NVIDIA_DRIVER_CAPABILITIES:+$NVIDIA_DRIVER_CAPABILITIES,}graphics
    
    USER root
    RUN apt -y update
    RUN apt -y install vim
    COPY ./.bashrc /root/

    매번 입력하기 귀찮으니 ros 강의 자료에 있는 alias를 참조하여 .bashrc를 루트 홈에 넣었다. 처음 컨테이너를 실행할 때 entrypoint로 bashrc를 자동으로 실행하는데, 두번째 부터는 같은 컨테이너에 붙여도 bashrc를 실행하지 않는다. docker exec 옵션에 없는 듯 하다.

    now0930@amd2004:~/dockerBuild/ros$ docker exec -it noetic_ros /bin/bash
    root@amd2004:/# sds

    매번 컨테이너에 들어간 후 sds를 실행해야 하여 귀찮다.

    now0930@amd2004:~/dockerBuild/ros$ cat .bashrc 
    alias eb='vi ~/.bashrc'
    alias sb='source ~/.bashrc'
    alias cma='catkin_make -DCATKIN_WHITELIST_PACKAGES=""'
    alias cop='catkin_make --only-pkg-with-deps'
    alias sds='source /opt/ros/noetic/setup.bash'
    alias axclient='rosrun actionlib axclient.py'
    set -o vi

    xhost로 local을 추가하여 docker 출력을 돌린다. docer run을 다음과 같이 한다.

    now0930@amd2004:~/dockerBuild/ros$ sudo xhost +local:docker
    [sudo] now0930 암호: 
    non-network local connections being added to access control list
    now0930@amd2004:~/dockerBuild/ros$ xhost 
    access control enabled, only authorized clients can connect
    LOCAL:
    INET:localhost
    SI:localuser:now0930
    now0930@amd2004:~/dockerBuild/ros$ 
    #!/bin/bash
    nvidia-docker run -it -v /run/user/1000:/run/user/1000 -v /dev:/dev -v /tmp/.X11-unix:/tmp/.X11-unix:ro \
    	-v /home/now0930/ros_test:/home/ros_test --name noetic_ros \
    	--privileged --ipc=host --shm-size=512m --net=host -e DISPLAY=$DISPLAY \
    	-e XDG_RUNTIME_DIR=/run/user/1000 --runtime=nvidia \
    	osrf/ros_custom:noetic-desktop-full 
  • 예제로 배우는 도커

    예제로 배우는 도커

    isbn: 9791161754734

    책에 예제 가득하게 있다. 이런 경우가 필요한가 싶을 정도 과한 부분이 있다. 저자같이 인프라를 전문적으로 구축하다 보면 별 경우가 다 있겠지만, 일반인이 그런 경우를 마주칠 지 모르겠다. 반을 넘어가는 뒤쪽에서 저자가 무슨 말을 하는지 잘 모르겠다.

    docker를 한 번 쓰기 시작하면, 너무 편해 다른 방식으로 환경을 설정할 생각을 하지 않는다. 오픈소스가 만든 파편화 지옥에서 많은 인간들을 구원했다. 당장 나도 apache, mysql, phpmyadmin 정도 돌리는데 더 알아보지 않고 docker 이미지를 찾아 다닌다. 편하다.

    docker container 5개 정도만 돌려도 docker compose를 알아두면 편할 듯 하다. 다음에 좀 배워 놔야 겠다.

  • 완벽한 IT 인프라 구축을 위한 Docker

    완벽한 IT 인프라 구축을 위한 Docker

    isbn: 9788956747903

    서버를 다시 설정하는 과정 중 Docker가 어떤 물건인지 이해하려 책을 선택했다. 초판이 2016년 출판 되었는데, it와 거리가 있어 보이는 일본 작가가 책을 썼다. 지금이야 사람들이 많이 docker를 사용하여 인터넷에서 많은 정보를 쉽게 찾는데, 2016년에 docker 가능성을 보고 어렵게 정보를 수집, 정리하여 책을 낸 저자 판단이 시대를 읽었다 본다. 너무도 파판화딘 리눅스 인프라 구축에 많은 고통을 받았다 본다.

    처음 접하는 사람도 쉽게 읽을 수 있게 책을 썼다. Dockerfile로 빌드 정도는 할 수 있지만, 네트웍 설정, 볼륨 설정 등 복잡한 내용이 많다. entrypoint, cmd 활용 예시만 이해해도 책을 읽을 가치가 있다. 인터넷을 한없이 찾기보다, 이런 저자가 쓴 쉽게 읽히는 책을 읽는 게 더 빠르다. cmd와 entrypoint로 옵션을 전달하는 방법은 신박하다.

    파편화된 리눅스 생태계에서 docker가 삶을 편한하게 한다. 아 내 두달치 기록. docker로 설정했으면 아직도 살아 있을지도…