Let’s go!

  • 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로 설정했으면 아직도 살아 있을지도…

  • 서버 재설치 feat. docker

    mysql을 8.0으로 업데이트 하면서 기존 데이터 베이스가 날아갔고, 다시 복구되지도 않았다. 이번 기회에 서버를 재설치 하고 요즘 뜨는 docker로 서비스를 돌리기로 해다. 의지는 있지만 docker 기본 개념과 철학을 잘 이해하지 못한 상태에서 apache, mysql을 연동하는데 너무나 어려웠다.

    • docker container는 한 개 daemon만 실행한다.
    • 여러 daemon이 필요하면 container를 새로 만든다.
    • docker build 옵션 중 cmd ,entrypoint는 마지막 한 개만 유효하다.
    • docker run에 –link 옵션으로 다른 container를 연결하면 hosts 파일에 container 이름이 추가된다. 다른 container에 이름으로 접근할 수 있다.
    • docker run 중 -p 옵션으로 포트를 설정하지 않으면 expose 옵션으로 열린 포트를 외부에서 접근할 수 없다.
    • mysql docker image에 bind-address 옵션이 없고, 넣어도 역할을 하지 않는다.
    • link 옵션 대신 network으로 추가할 수 있는데, 힘들어서 못 하겠다.
    • mysql 로 MYSQL_ROOT_PASSWORD로 실행한 후 mysql < file.sql로 복구한 뒤, flush priviliges로 복구 파일 password를 적용시켜야 한다. 파일에 저장된 root password로 데이터 베이스 비밀번호를 초기화 할 수 있다.
    • https 설정시 lets encrypt로 받은 키를 configure file에 default에 넣지 않고 별도 virtual host를 설정하면SSL_ERROR_RX_RECORD_TOO_LONG 가 뜬다.
    • apache에서 database에 접근하기 위한 사용자 이름, 패스워드를 별도 파일을 만들어 접근할 때, docker container에 넣어 줘야 한다.

    이 밖에도 수 많은 시행 착오가 있었다. 게다가 가장 최근 백업 파일이 두 달 전 파일이었다. 주중에 한 번씩 백업 하도록 수정했다. 설정하기는 힘들었어도 사용해 보니 편하다. 간단한 업데이트로 서버를 재설장 한다는게 말도 안되지만 잦은 빈도로 발생한다. phpmyadmin도 설치해야 하는데, 지금 엄두가 안 난다.

    두 달치 기록을 날리고 값진 경험을 했다. 아직도 복구 중…