Kobuki를 실행 후기

 

kobuki

 

kobuki를 실행하기 전에 turtlebot3을 실행해 봤기 때문에 조금 수월하게 진행할 수 있었습니다.

그나마 수월하다고 생각했는데 4일이나 걸렸네요..ㅠㅠ

kobuki를 실행중 시행착오

1. yujin robot의 패키지 안에 slam과 navigation package가 없어서 turtlebot3의 package를 이용하였는데 clone을 잘못하였는지 catkin_make에서 계속 오류가 떠서 catkin_ws를 한번 밀고 다시 시도하였습니다.

 

2. 어제는 되던 센서가 오늘 갑자기 안 되는 문제가 발생하였는데 처음에는 연결부의 문제점인가 해서 포트 위치를 바꿔가며 했지만 혹시나 해서 노트북을 reboot 한 후 $ lsusb 를 했더니 제대로 다 연결되는 것을 확인할 수 있었습니다.

얼마나 허무하던지...

 

3. slam을 할 때 rosbag을 이용하여 lidar값을 다 저장하고 저장된 값을 이용하여 지도를 만들도록 하려고 했는데 이때 rosbag이 불러와야 할 데이터가 이전 시간의 데이터인데 제대로 불러오지 못해 지도를 만들지 못했습니다. 이를

$ rosparam set use_sim_time ture를 실행시킨 후 다시 rosbag play를 하니까 제대로 데이터를 불러올 수 있었습니다. 

 

4. turtlebot3의 package를 그대로 가져와서 사용하다 보니 navigation을 할 때 kobuki가 받아들이는 토픽과 navigation의 launch파일에서 받아오라고 하는 토픽의 이름이 달라서 navigation이 제대로 실행됐음에도 불구하고 로봇이 움직이지 않는 문제점이 발생하였습니다. rqt를 통해 토픽이 다르다는 것을 알아채고 launch파일의 default값을 바꿔주니까 제대로 실행되는 것을 확인할 수 있었습니다.

 

5. navigation을 실행하기 전에 로봇의 위치를 맞추기위해 키보드조종 launch파일을 실행시킨 후 끄지않고 바로 rviz에서 2D Nav Goal을 실행하니까 로봇이 가다가 멈췄다가 하는 일이 발생하였습니다. 그 이유가 키보드명령으로 멈추라고 신호를 내보내는데 navigation이 가라고 신호를 보내니까 충돌이 생겨서 가다가 멈췄다가 하는것이었습니다. 키보드launch파일을 끄고 했는데도 그 전만큼은 아니었지만 그래도 조금은 버벅거리는것이 보이긴했습니다. 

그건 왜그럴까요....(아시는 분 댓글로 알려주세요ㅠㅠ)

 

6. 실행 파일 에러

robot@robot-900X3L:~/catkin_ws$ roslaunch kobuki_keyop keyop.launch
RLException: [keyop.launch] is neither a launch file in package [kobuki_keyop] nor is [kobuki_keyop] a launch file name
The traceback for the exception was written to the log file

 

해결방법 :

$ source ~/catkin_ws/devel/setup.bash

 

다 실행해보고 난 후..

kobuki를 navigation까지 실행시키는데 4일이 걸렸습니다. 원래 계획은 이틀 만에 성공하는 것이었는데 생각보다 오류가 많아서 빨리 성공하지 못했던 것 같습니다. 오류 해결을 빨리 할 수 있도록 ros 공부를 더 열심히 해야겠네요..

왜 하면 할수록 더 모르겠는지...ㅠㅠ 

 

 

필요한 파일과 tutorial들은 아래의 github사이트에 들어가면 볼 수 있습니다.

github.com/yehjin00/Kobuki

 

yehjin00/Kobuki

kobuki keyteleop tutorial. Contribute to yehjin00/Kobuki development by creating an account on GitHub.

github.com

 

 

참고 사이트
https://emanual.robotis.com/docs/en/platform/turtlebot3/overview/
https://github.com/yujinrobot/kobuki
https://github.com/gaunthan/Turtlebot2-On-Melodic

앞의 게시물의 마지막 이미지를 보면 차선 이외에 주변의 많은 다른 픽셀들이 감지되는 것을 볼 수 있습니다. 이를 제거하기 위해 ROI(Region Of Interest), 즉 관심 영역을 지정해야 합니다.

 

카메라가 차량 전면에 고정돼있다고 하면 차선은 항상 이미지의 동일한 영역에 나타납니다. 보고 싶은 부분만 잘라내어 차선이라고 생각되는 부분만 본다는 것입니다. 여러 모양으로 ROI를 지정할 수 있는데 우선 삼각형으로 만들어보겠습니다. 그럼 삼각형 내부에 있는 흰 픽셀이 차선임을 의미하겠죠?

 

코드에 적힌 test.jpg 이미지는 차선 인식(1) 게시물에 있습니다. 

2021.04.26 - [Udacity/computer vision & deep learning] - 차선인식(1) - 색으로 차선인식

 

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np

# Read in the image and print some stats
image = mpimg.imread('test.jpg')
print('This image is: ', type(image), 
         'with dimensions:', image.shape)

# Pull out the x and y sizes and make a copy of the image
ysize = image.shape[0]
xsize = image.shape[1]
region_select = np.copy(image)

# 삼각형 모양으로 roi 지정하기
# 아래의 세가지 변수를 바꿔가며 삼각형 모양안에 차선이 다들어오도록 만들어 줍니다.
left_bottom = [70, 315]
right_bottom = [497, 315]
apex = [280, 190]

# np.polyfit()함수는 괄호안에 x좌표, y좌표, 차수를 넣으면 두 점을 연결한 직선의 기울기와 y절편을 알려줍니다.
fit_left = np.polyfit((left_bottom[0], apex[0]), (left_bottom[1], apex[1]), 1)
fit_right = np.polyfit((right_bottom[0], apex[0]), (right_bottom[1], apex[1]), 1)
fit_bottom = np.polyfit((left_bottom[0], right_bottom[0]), (left_bottom[1], right_bottom[1]), 1)

# 위에서 그린 선 안에 있는 모든 픽셀을 선택합니다.
XX, YY = np.meshgrid(np.arange(0, xsize), np.arange(0, ysize))
region_thresholds = (YY > (XX*fit_left[0] + fit_left[1])) & \
                    (YY > (XX*fit_right[0] + fit_right[1])) & \
                    (YY < (XX*fit_bottom[0] + fit_bottom[1]))

# 위에서 선택한 픽셀의 색을 빨간색으로 만든다. 즉, roi부분을 빨간색으로 만든다.
region_select[region_thresholds] = [255, 0, 0]

# Display the image
plt.imshow(region_select)

# 그래프가 나타나지않으면 아래의 주석을 풀면됩니다.
# plt.show()

 

위의 코드를 실행했을 때 결과 이미지는 아래와 같습니다.

 

 

그럼 roi내부를 모두 빨간색으로 하는 것이 아니라 차선만 빨간색으로 만들어 보겠습니다.

 

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np

# Read in the image
image = mpimg.imread('test.jpg')

# Grab the x and y sizes and make two copies of the image
# With one copy we'll extract only the pixels that meet our selection,
# then we'll paint those pixels red in the original image to see our selection 
# overlaid on the original.
ysize = image.shape[0]
xsize = image.shape[1]
color_select= np.copy(image)
line_image = np.copy(image)

# Define our color criteria
red_threshold = 200
green_threshold = 200
blue_threshold = 200
rgb_threshold = [red_threshold, green_threshold, blue_threshold]

# Define a triangle region of interest (Note: if you run this code, 
# Keep in mind the origin (x=0, y=0) is in the upper left in image processing
# you'll find these are not sensible values!!
# But you'll get a chance to play with them soon in a quiz ;)
left_bottom = [70, 315]
right_bottom = [497, 315]
apex = [280, 190]

fit_left = np.polyfit((left_bottom[0], apex[0]), (left_bottom[1], apex[1]), 1)
fit_right = np.polyfit((right_bottom[0], apex[0]), (right_bottom[1], apex[1]), 1)
fit_bottom = np.polyfit((left_bottom[0], right_bottom[0]), (left_bottom[1], right_bottom[1]), 1)

# Mask pixels below the threshold
color_thresholds = (image[:,:,0] < rgb_threshold[0]) | \
                    (image[:,:,1] < rgb_threshold[1]) | \
                    (image[:,:,2] < rgb_threshold[2])

# Find the region inside the lines
XX, YY = np.meshgrid(np.arange(0, xsize), np.arange(0, ysize))
region_thresholds = (YY > (XX*fit_left[0] + fit_left[1])) & \
                    (YY > (XX*fit_right[0] + fit_right[1])) & \
                    (YY < (XX*fit_bottom[0] + fit_bottom[1]))
# Mask color selection
color_select[color_thresholds] = [0,0,0]
# Find where image is both colored right and in the region
line_image[~color_thresholds & region_thresholds] = [255,0,0]

# Display our two output images
plt.imshow(color_select)
plt.imshow(line_image)

# uncomment if plot does not display
# plt.show()

 

위의 코드의 결과이미지는 다음과 같습니다.

 

 

'Udacity > computer vision & deep learning' 카테고리의 다른 글

차선인식(1) - 색으로 차선인식  (0) 2021.04.26

이미지에서 차선을 찾아보려고 합니다. 도로의 차선을 식별하기 위해서 필요한 것들이 무엇이 있을까요?

1. : 주로 차선은 흰색, 주황색으로 칠해져있습니다.

2. 모양 : 실선, 점선

3. 이미지에서의 위치 : 자동차에 장착된 카메라가 고정되어있기 때문에 차선은 항상 카메라 이미지에서 동일한 영역에                                  나타납니다. 

4. 방향(orientation) : 차량이 도로를 똑바로 향하고 있을 때 차선은 삼각형 모양으로 보입니다.


먼저 색으로 차선을 한번 찾아보려고 합니다.

차선이 흰색이라고 가정을 하면 이미지에서 흰색 픽셀을 어떻게 골라낼 것인가요?

이미지가 rgb채널(red-green-blue)로 이루어져 있다고 생각을 해봅시다. 각각의 채널은 0에서 255까지의 범위를 가지는데 0은 가장 어두운 부분, 255는 가장 밝은 부분을 의미합니다.

 

모든 이미지 파일은 픽셀(Pixel)이라는 것으로 이루어져 있습니다. 눈에 보이지는 않지만 아주 작은 크기의 사각형 단위인 픽셀에 색상이 넣어짐으로써 한 칸의 색이 완성이 되고, 그런 작은 사각형들이 모여 이미지를 완성시킵니다.

 

Quiz!

rgb채널에서 순수 흰색을 뽑아내고 싶으면 범위를 어떻게 지정해야 할까요?

더보기

답은 [255,255,255]입니다.


파이썬으로 흰색을 추출하는 코딩을 해보겠습니다.

 

test.jpg

이미지를 그려내기 위해서pyplotMatplotlib에 있는 image라이브러리를 불러옵니다. 또한 이미지를 수정/관리하기 위한 용도로 Numpy 사용합니다.

 

# matplotlib는 파이썬의 시각화 도구입니다.
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np

 

그런 다음 x  y 크기를 잡고 작업할 이미지의 복사본을 만듭니다.

이미지를 수정/관리할 때는/ 항상 Copy를 만드는 것이 좋습니다. 이미지에 직접 수정을 가하게 된다면 돌이킬 수 없을 수도 있기 때문입니다.

 

# 이미지를 읽고 몇가지 속성을 출력합니다.
image = mpimg.imread('test.jpg')
print('This image is: ',type(image), 
         'with dimensions:', image.shape)

# x와 y의 사이즈를 측정하고, 복사본을 만듭니다.
ysize = image.shape[0] #이미지의 높이
xsize = image.shape[1] #이미지의 너비
# Note: 단순히 "="를 사용하는 대신 항상 복사본을 만드십시오.
color_select = np.copy(image)

※ image.shape [이미지 높이, 이미지 너비, 채널 수] 

이미지에서 좌표축을 만들어보면 아래 사진과 같습니다.

위의 코드에서 ysize와 xsize가 왜 이미지의 높이와 너비를 의미하는지 알겠죠?


다음으로는 차선으로 뽑아낼 색의 임계값을 지정해 볼까요

아래의 임계값을 추출할 수 있도록 조정해야 합니다.

 

# 색상 선택의 기준을 정합니다.
red_threshold = 200
green_threshold = 200
blue_threshold = 200
rgb_threshold = [red_threshold, green_threshold, blue_threshold] # 3가지채널을 조합합니다.

 

다음으로는 임계값 아래의 픽셀들은 다 0, 즉 검은색으로 만들어 줍니다. 그럼 지정한 임계값보다 밝은 색상만 추출되고 임계값보다 어두운 색상은 검정색으로 출력됩니다. 임계값을 조정하다 보면 흰색만 이미지에 나타나게 됩니다.

 

※각각의 임계값을 모두 0으로 설정한 후 이미지를 출력하면 검은색으로 만들 부분이 없기 때문에 아무런 변화가 없는 것을 알 수 있습니다. 

 

# 임계 값 미만의 픽셀을 식별한다.
thresholds = (image[:,:,0] < rgb_threshold[0]) \
            | (image[:,:,1] < rgb_threshold[1]) \
            | (image[:,:,2] < rgb_threshold[2])
color_select[thresholds] = [0,0,0]

# 이미지를 보여준다.              
plt.imshow(color_select)
plt.show()
# 결과이미지를 저장하려면 아래코드를 입력하면됩니다.
# mpimg.imsave("test-after.png", color_select)

 

image [:,:,0]은 rgb에서 0번째 채널을 의미합니다. 코드를 해석해보면 0번째 채널인 빨간색 채널의 임계값이 지정해 놓은 rgb_threshold의 0번째행인 red_threshold값보다 작을 경우 임계값을 0으로 만들어준다는 것입니다.

다음은 임계값을 조정하여 가능한 많은 차선을 추출한 이미지입니다.

 

test-after.png

 

다음 게시물에 계속됩니다!

'Udacity > computer vision & deep learning' 카테고리의 다른 글

차선인식(2) - ROI지정하기  (0) 2021.04.26

realsense camera D435i에 대한 착각

처음에 D435i를 봤을 때 렌즈가 많아 보여서 당연히 stereo카메라인 줄 알았습니다. 그런데 realsense viewer와 rviz를 실행시켜 보았을 때 젤 오른쪽에 있는 렌즈만 카메라라는 것을 알게 되었습니다. 즉 monocular 카메라였던 것입니다. 카메라 종류를 착각하는 바람에 camera calibration을 실행시키는데 오래 걸렸네요...

 

 

왼쪽에서 첫 번째 렌즈와 세 번째 렌즈는 적외선을 내보내서 stereo방식으로 거리를 측정하는 데에 쓰입니다. 맨 오른쪽 렌즈를 제외하고는 depth정보를 받아들이는 데 사용하고 맨 오른쪽 렌즈는 RGB 카메라입니다. D435i는 이름에서 알 수 있듯이 imu 센서도 포함하고 있습니다. 

 

※imu센서: 관성을 측정하여 최종적으로 구하고자 하는 값은 물체가 기울어진 각도를 정확하게 측정하는 것


1. realsense 실행시키기

github.com/IntelRealSense/realsense-ros

 

IntelRealSense/realsense-ros

Intel(R) RealSense(TM) ROS Wrapper for D400 series, SR300 Camera and T265 Tracking Module - IntelRealSense/realsense-ros

github.com

이 사이트를 따라 하면 됩니다.

roscore를 실행시킨 후 마지막에 아래의 코드를 실행시키고 $ rviz를 하면 됩니다.

 

$ roslaunch realsense2_camera rs_camera.launch

 

토픽이 다르면 rviz 에서 카메라가 뜨지 않는데 이는 $ rostopic list를 통해 확인할 수 있습니다.

저는 토픽이 /camera/color/image_raw 였기 때문에 아래와 같이 토픽을 설정해 주었습니다.

rviz에서 왼쪽 하단에 Add라는 버튼을 누르고 By topic에서 color 누르고 image를 클릭 후 ok 하면 왼쪽 하단에 화면이 나올 것입니다.

 


2. Camera Calibration

wiki.ros.org/camera_calibration

 

camera_calibration - ROS Wiki

kinetic melodic noetic   Show EOL distros:  EOL distros:   electric fuerte groovy hydro indigo jade lunar diamondback: Only showing information from the released package extracted on Unknown. No API documentation available. Please see this page for in

wiki.ros.org

이 사이트를 따라라 하면 됩니다. d435i이기 때문에 monocular tutorial을 따라 했습니다.

calibration도 쉽지 않네요... tutorial그대로 따라 하는데 왜 자꾸 오류가 나는지..ㅠㅠ

 

  •  첫 번째 오류: rosdep error
ERROR: Rosdep cannot find all required resources to answer your query
Missing resource camera_calibration
ROS path [0]=/opt/ros/melodic/share/ros
ROS path [1]=/home/yehjin/catkin_ws/src
ROS path [2]=/opt/ros/melodic/share

  해결방안:

$ sudo apt-get install ros-kinetic-image-pipeline
$ rosdep install camera_calibration

 

  •  두 번째 오류: cv_bridge error

해결방안:

$ git clone -b melodic --single-branch https://github.com/ros-perception/vision_opencv.git

 

  • 세 번째 오류: service error

 

service를 찾을 수 없다는 오류가 떴습니다.

 

  해결방안:

 

$ rosrun camera_calibration cameracalibrator.py --size 8x6 --square 0.108 image:=/camera/image_raw camera:=/camera --no-service-check

 

위의 코드로 바꿨더니 에러가 생기지 않았습니다. 사이트에 있는 건데 왜 빨리 발견 못했을까요..ㅎ

 

  • 두 번째 오류: topic error

 

 

어떤 것을 실패했다면서 display에 아무것도 뜨지 않았습니다. 이건 위의 코드에서의 토픽과 내 토픽이 달랐기 때문이더라고요.

 

해결방안:

 

 

토픽을 사진의 표시된 것으로 바꾸고 나니까 실행이 됐습니다.

이 두 개의 오류를 고치고 나서야 드디어 성공! 캘리브레이션이 잘 되기 위해서는 종이가 평평한 곳에 아주 밀착되어있어야 합니다.

그래서 저는 아래와 같이 벽에 한 후 종이를 고정하고 카메라를 움직이는 것보다 카메라를 고정하고 종이를 움직이는 것이 대부분 사용하는 것이란 걸 알고 다시 시도했습니다.

 

 

calibrate 버튼을 누르면 아래와 같이 calibrtaion결과를 알려줍니다.

 

 

체스판을 위의 사진처럼 인식하였고 카메라를 여러 각도와 거리로 옮겨가면서 체스판을 인식하게 하여 67개의 sample을 이용해서 calibration을 해보았습니다.

나온 결과를 저장하고 싶으면 display창에 commit 버튼을 누르고 save를 누르면 젤 아래에

 

('Wrote calibration data to', '/tmp/calibrationdata.tar.gz')

 

이와 같은 문장이 나오는데 /tmp/ 저 부분이 저장된 경로를 의미합니다.

tar.gz는 압축파일인데 이를 압축 해제하면 calibration 할 때 사용한 이미지들을 볼 수 있습니다.

 

# tmp폴더에 들어가서 tar -zxvf [파일이름] -C [압축해제할 위치]
yehjin@yehjin-900X3L:/tmp$ tar -zxvf calibrationdata.tar.gz -C ~/catkin_ws

글을 마치면서

아직 토픽에 대해 익숙하지 않다는 것을 알게 되었습니다. ros공부를 좀 더 해야겠네요..

 

* 참고

hs929 kr 님의 블로그
https://mushr.io/tutorials/realsense/

 

+ Recent posts