======Meerkat====== 미어켓은 소형 매장(편의점)등에서 재고를 정리해주는 로봇입니다. 낮은 곳에 있는 재고를 정리할때의 불편함을 덜어주고 또한 자동으로 돌아다니며 부족한 물품을 그때 그때 채워넣어서 편의성 또한 증가할 수 있습니다. =====1. 개요===== 2020년 미어켓 프로젝트입니다! {{https://img.kasimov.synology.me/reference/meerkat/meerkat-1.jpg?500}} 메니퓰레이터가 서있는 모습이 미어켓과 닮아서 이름을 짓게 되었습니다. ====1.1. 참가자==== **박정은**\\ 팀장, 주행 소프트웨어 개발\\ **김경남**\\ 설계 및 매니퓰레이터 개발 **김성진**\\ 주행 하드웨어 개발 ====1.2. 목적==== 미어켓은 소형 매장(편의점)등에서 재고를 정리해주는 로봇입니다. 낮은 곳에 있는 재고를 정리할때의 불편함을 덜어주고 또한 자동으로 돌아다니며 부족한 물품을 그때 그때 채워넣어서 편의성 또한 증가할 수 있습니다. ====1.3. 기능==== 미어켓은 크게 두가지 기능으로 동작합니다.\\ 1. 길 찾기\\ 원하는 목표 위치로 이동합니다. 로봇의 현재 위치를 IMU와 DEPTH 카메라 정보를 퓨전하여 추정하며, 위치 정보와 라이다 정보를 입력으로 한 강화학습을 적용합니다. 2. 물건 인식 후 집기\\ 물건의 숫자를 보고 인식한 뒤, 흡착 그리퍼를 사용해 이를 집어서 옮깁니다. ====1.4. 출품==== 칼만 필터를 사용한 IMU와 DEPTH 카메라 퓨전에 대하여 주행 소프트웨어를 삼성 SOSCON AI Robotics KR 커뮤니티 세션에서 발표 예정. =====2. 주행 개발 일지===== 코드는 https://github.com/jeongeun980906/meerkat ====2.1. 개요==== 주행 개발은 크게 모터 제어와 자세 추정, 그리고 네비게이션으로 나눌 수 있습니다. 우리는 여기서 TAMIYA TT02라는 차량을 사용하였으며 아두이노를 사용하여 제어하였습니다. INTEL REALSENSE 435i 뎁스 카메라와 아두이노 MPU 6050 IMU를 퓨전하여 위치를 추정하였습니다. 이러한 퓨전 값들을 활용하여 강화학습을 통한 네비게이션을 진행하였습니다. 리얼센스 노드에서 받은 뎁스와 rgb 정보를 **카메라 노드**에서 받아서 차량의 좌표계를 world 좌표계로 바꾸어 x,y,yaw 값을 publish 해줍니다. 그 후 **강화학습 노드**에서 이미 훈련된 가중치들을 불러온 뒤, 라이다 스켄 정보와 목표 좌표계상의 좌표를 신경망의 input으로 널어줍니다. 여기서 목표 좌표계상의 위치는 **serial_node2**에서 받은 IMU값과 전에 publish된 x,y,yaw값을 퓨전 한 뒤, 좌표 변환을 하여 추정합니다.인공 신경망 output으로 5가지 action 중 하나가 나오게 되면 그것에 맞게 차량의 속도와, steering angle 정보를 아두이노에 publish해줍니다. 이 정보를 받은 **serial_node**에서 아두이노를 제어하여 차량을 움직이게 합니다. {{https://img.kasimov.synology.me/reference/meerkat/sum.png?1000}} ====2.2. 아두이노==== 차량은 Tamiya TT02 사용. ESC 또한 내장되어 있는 것을 사용하였습니다. 차량의 후진을 하기 위하여 중반에 L293D 모터 드라이버 칩을 이용하였습니다. 하지만 중반에 드라이버와 빵판이 녹아버렸는데 여분이 없어서 드라이버 사용을 못하고 전진만 할 수 있었다는 슬픈 사연이 있었습니다ㅜㅜ\\ [[http://wiki.vctec.co.kr/opensource/arduino/dcmotordirection|L293D reference]]\\ ROSSERIAL을 사용하여 하나의 아두이노에서는 velocity(throttle)과 Steering angle의 값을 Subscribe하도록 코딩하였습니다. \\ 또한 다른 아두이노를 하나 더 사용하여 IMU값을 String 형식으로 Publish 하는 노드를 만들었습니다. 원래는 rosserial_python serial_node를 두번 실행 할 수 없어서 모든 것을 복붙한 새로운 패키지에 serial_node2.py라는 런파일을 만들어서 활용하였습니다. \\ "A: gyro_x B: gyro_y C: gyro_z D: acc_x E: acc_y F: acc_z" \\ 형식의 String type메세지가 실행이 됩니다. \\ 코드에 관한 설명은 [[https://github.com/jeongeun980906/meerkat|meerkat_github]] 참조하시면 됩니다. ====2.3. 자세 추정==== 로봇의 현재 위치는 뎁스 카메라의 정보를 바탕으로 추정하였습니다. 로봇위의 두개의 노란색과 녹색의 지표를 인식하여 각각의 픽셀 좌표계를 카메라 좌표계로 변환 한 뒤, 이를 다시 World coordinate로 변환하는 작업을 하였습니다. 이 world coordinate 기준의 뎁스 기반 로봇 위치를 IMU 센서의 값과 퓨전하여서 위치를 추정하였습니다. 픽셀 좌표계를 카메라 좌표계로 바꾸는 식은 아래와 같습니다.\\ x_cam = (x_pix - x_principal)*depth/focal_length_fu y_cam=(y_pix - y_principal)*depth /focal_length_fv 뎁스의 x,y,theta정보와 IMU의 ax,ax,theta_dot 정보를 사용하여 x,y,yaw,x_dot,y_dot,theta_dot을 추정하는 시스템 식은 아래와 같습니다.\\ process update\\ {{https://img.kasimov.synology.me/reference/meerkat/f.png?800}}\\ measurement update\\ {{https://img.kasimov.synology.me/reference/meerkat/h.png?500}}\\ 칼만 필터의 식은 다음과 같습니다.\\ {{https://img.kasimov.synology.me/reference/meerkat/kf.jpg?700}}\\ 이를 활용하여 매 스탭마다 칼만 필터를 업데이트 해가며 자세를 추정하였습니다.\\ 칼만필터의 Q와 R값은 True Noise를 알 수 없으므로 테스트를 통하여 최적의 임의의 값을 선정하였습니다. 자세한 내용은 깃허브 코드 참조 ====2.4. 네비게이션==== 네비게이션은 강화학습을 사용하였습니다. \\ 알고리즘은 Per-D3QN 이라는 정식 명칭은 아니지만 **Duel DQN + Double DQN + Prioritized Experience Replay** 3가지 논문을 합친 알고리즘입니다. \\ [[https://arxiv.org/abs/1509.06461|Double DQN]]\\ [[https://arxiv.org/abs/1511.06581|Duel DQN]]\\ [[https://arxiv.org/abs/1511.05952|Prioritized Experience Replay]]\\ **INPUT** 값은 world coordinate 기준 로봇의 x,y,yaw(Kalman Filter Output)와 목표 x_o,y_o에 대하여 목표 좌표를 로봇의 현재 좌표계로 바꿔주어서 bxo,ybo (object seen from robot body)와 라이다의 360개의 스캔 데이터 값을 넣어주었습니다. 여기서 좌표값과 라이다 값은 자료 크기가 차이가 나지만 모두 가중을 두어야 하므로 두개의 인풋 단으로 나누어 네트워크를 만들었습니다. 여기서 시뮬레이터상의 값이 실제와 비슷하게 하기 위하여 미리 돌려본 칼만 필터의 공분산 행렬 (P)를 활용하여 노이즈를 추가하였습니다. **NN** 아키텍쳐는 다음과 같습니다.\\ {{https://img.kasimov.synology.me/reference/meerkat/nn.jpg?500}}\\ **Action**은 총 5개로 Steering Wheel이 각각 60,75,90,105,120일 때 입니다.\\ 각각의 경우에 대한 선속도와 각속도는 미리 돌려본 칼만 필터에서의 3,4,5 행의 값을 활용하였고 실제 동역학은 노이즈가 굉장히 많으므로 위와 마찬가지로 미리 돌려본 칼만 필터의 공분산 행렬 (P)를 활용하여 노이즈를 추가하였습니다. \\ **Reward**식은 다음과 같습니다\\ reward=(origin-distance)/origin+5*(1-abs(theta)) 현재 내가 향하는 방향이 골 지점과 얼마나 일치 하는지와 처음 위치에 비하여 골 위치가 얼마나 먼지를 더하였습니다.\\ 여기서 현재 향하는 방향에 좀 더 가중을 두며 감가율을 0.7으로 낮춰 현재의 행동+ 몇스텝 더 에만 집중하도록 설계하였습니다. \\ 이렇게 할 경우 장애물 근처에 아예 안가기 보다 가까이가면서도 회피하는 모션이 나올 수 있었습니다. \\ 노이즈가 없을 때 돌려본 강화학습의 결과는 다음과 같습니다. \\ {{https://img.kasimov.synology.me/reference/meerkat/clean_res.png?1000}}\\ 왼쪽은 평균 성공률, 오른쪽은 평균 보상. 평균 보상이 높을수록 현재 행동이 최적 행동에 가깝도록 설계하였습니다.\\ 기존 로보티즈 코드를 활용하였으며 기존 로보티즈는 성공률이... 10프로가 간당간당 했다\\ 칼만필터로 인해 얻은 선속도,각속도, 동역학의 분산들과 Input에 분산 만큼의 노이즈를 주었을 때의 결과는 다음과 같습니다. \\ action을 3가지로 줄이고 현실에 맞게 time step을 늘렸기 때문에 평균 보상은 많이 줄어들었지만 나쁘지 않은 성공률을 보였습니다.\\ {{https://img.kasimov.synology.me/reference/meerkat/noisy_res.png?1000}}\\ 마지막에 강화학습 학습한 코드롤 실 로봇에 돌려봤어야 했으나 건강의 문제 + 시간의 문제로 인하여 포기했습니다ㅜㅜ ====2.5. 향후 과제==== 미어켓의 궁극적인 목표는 뎁스 카메라가 아닌 일반 매장에 붙어있는 CCTV를 활용하는데에 있습니다. 하지만 강화학습을 활용한 네비게이션은 시뮬레이터 상이 아닌 현실에서 학습하기에는 너무 위험하고 어렵습니다. 여기서 심지어 시뮬레이터상에서의 RGB 사진 값은 실제와 너무 다르기 때문에 RGB 카메라가 아닌 depth 카메라를 활용하여 좌표를 input에 넣게 되었습니다. **현실이 아닌 가상환경에서만 학습**이라는 제약 조건을 지키기 위하여 input값을 카메라 값으로 하는 것을 포기하여야 했습니다.\\ 하지만, 좌표 정보로 잘 움직인다면, 우리는 **모방학습**을 시도해 볼 수 있을 거 같습니다. 전에 학습해 놓은 Depth 정보로 Policy(Q_value)를 만들고 RGB 값을 Input으로 하는 새로운 뉴럴 네트워크의 policy (Q_value)를 단순한 지도학습으로 학습하는 방법이나, 역강화학습, 혹은 다른 모방학습 알고리즘을 활용한다면, 안전하게 현실에서 학습 할 수 있을 것입니다. \\ **단순 지도 학습** 위 **GAIL 역강화학습** 아래 \\ {{https://img.kasimov.synology.me/reference/meerkat/future.png?700}}\\ =====3. 로봇팔 개발일지===== ====3.1. 개요==== 미어캣 로봇팔의 초기모델의 경우 중요하게 여겨지는 로봇팔의 능력은 문열기 능력이었다. 직접 방문을 열고 방에 들어간 뒤 원하는 목표에 있는 물건을 집고, 목표하는 위치에 물건을 놓는 능력을 가지는것을 목표로 하였다. 이러한 상황에서 우린 필요한 모션제어 방법에 관해 우선 정리해보았다. 첫번째론 목표하는 위치까지 이동하는 모션 플래닝이다. 이 플래닝을 통해 우린 로봇팔로 물체를 집을 수 있게 된다. 2번 째론 가장 중요하고 여려운 문을 여는 모션 플래닝이다. 여기서 주의깊게 봐야할 것은 문을 열 ====3.2. 6-DOF manipulator==== ====3.3. Dynamixel-workbench==== ubuntu상에서 ros를 통해 dynamixel을 직접 제어할 수 있다. 일반적인 모터의 경우 아두이노를 통해 제어하나 robotis에서 나온 dynamixel 모터 같은 경우 노트북에서 바로 신호를 보내 모터를 제어 가능하다. Window상에선 추가적인 프로그램을 설치해야하나, Ubuntu 상에선 robotis에서 배포하고 있는 dynamixel-workbench 패키지로 dynamixel을 노트북으로 제어 가능하다. 이 dynamixel을 src폴더에 넣고 catkin-make 이후 이 패키지를 실행하면 메세지 타입 중 하나인 service를 통해 dynamixel의 모터 각도를 제어할 수 있다. 이를 응용하면 모바일 로봇같이 바퀴를 구동하는 모터로 dynamixel을 활용 가능하고, 로봇팔같이 정밀한 제어가 필요한 서보모터로써 dynamixel을 활용 가능하다. ====3.4. Ros-moveit==== 일반적인 로봇팔 제어의 경우 크게 3가지 motion planning이 있다. 첫번째론 로봇팔의 각 모터마다 원하는 angle값을 줘서 end-effector의 위치를 제어하는 방법이다. 이 방법의 경우 우선 각 모터의 angle값을 조작하는 방법이 있고 2번째론 end-effector의 목표 위치로 이동하기 위해 목표 위치에 다다를 수 있는 역기구학을 통해 모터 각도를 계산해서 ====3.5. 향후 과제====