본문 바로가기

개인 프로젝트

2022-1 PID제어를 이용한 밸런싱 로봇 만들기 #3

반응형

[IMU 공부, 노드 제작1]

imu에 대해 이론적인 부분을 공부하고 몇 가지 실습도 해보았다.


공부할 때 여러 블로그를 참고했고 실습(아두이노 코드)의 경우는 아래 블로그의 코드를 사용했다.


https://rasino.tistory.com/325#google_vignette

 

【 아두이노모듈#30】 #1.기울기 센서(6축 가속도&자이로)에 대해 알아봅시다.(GY-521/MPU6050 센서 실

【 아두이노모듈#30】 #1.기울기 센서(6축 가속도&자이로)에 대해 알아봅시다. 【 기울기 센서 개요 】 자이로 센서(Gyro Sensor)의 원리는 자이로스코프가 내장된 물체가 회전 운동을 하면 생기는

rasino.tistory.com



●Keyword
-RPY, 가속도 센서, 자이로스코프, 드리프트 현상, IMU, 상보 필터

 


●Study
RPY(Roll-Pitch-Yaw) :
-시스템의 기울기를 어떤 좌표축을 기준으로 표현

-

https://www.researchgate.net/figure/a-Pitch-yaw-and-roll-angles-of-an-aircraft-with-body-orientation-O-u-v-original_fig7_348803228




가속도 센서(Accelerometer) :
-가속도를 측정하는 센서


-imu에선 지구 중력가속도가 작용하는 방향을 토대로 시스템의 roll과 pitch를 계산함


-중력은 항상 z축 방향으로 작용하기에 z축 회전인 yaw는 가속도 센서로 측정 불가능함


-운동 중인 시스템의 법선, 구심 가속도가 가속도계에 영향을 주므로 기울기 측정에 에러를 발생시킴

+) 물론 등속 운동은 영향을 주지 않지만 등속 운동은 현실에서 매우 특별한 상황이므로 제외하고 생각




자이로스코프(Gyroscope) :
-각속도(rad/s)를 측정하는 센서


-MEMS(미세기전시스템)을 이용함

+)기구학에서 짧게 다룬 적 있는 내용, joint가 없는 기구인 Compliant Mechanism(유연기구)를 사용함


-각속도를 시간에 대해 적분해서 초기값에 대해 회전한 각도를 알아낼 수 있음

+)때문에 초기값이 0, 최초 시스템이 수평이라는 조건하에서만 현재 기울기를 계산할 수 있음


-가속도 센서와 달리 yaw까지 알아낼 수 있음


-노이즈, 에러에 의한 측정값도 적분에 의해 누적되어 정지한 상태에서도 오차가 점차 커지는 드리프트(drift)현상 발생

gy-521의 자이로스코프를 사용해 확인한 드리프트 현상이다. 센서를 가만히 놓아두고 측정했음에도 0에서 점차 측정값이 벌어진다.


또 그래프가 가속도 센서와 달리 매끈한 선으로 나왔다.




IMU(Inertial Measurement Unit) :
-가속도 센서, 자이로스코프, 지자기 센서를 갖고 있어 시스템의 가속도, 각속도, 지자기를 측정할 수 있는 장치


-보통 위 측정값을 이용해 시스템의 기울기(RPY)를 계산하는 데 사용


-특정 1개 센서로 RPY를 측정할 수도 있지만 오차를 줄이기 위해 2개 이상의 센서와 필터를 사용함


-'가속도 센서 + 자이로스코프 + 필터' 로 시스템의 roll과 pitch를, '자이로스코프 + 지자기 센서 + 필터'로 yaw를 비교적 정확하게 구할 수 있음


-r과 p를 구하는 데에는 상보 필터와 칼만 필터가 많이 사용됨


-현재 갖고 있는 gy-521은 mpu6050을 사용한 모델로 지자기 센서는 없기에 yaw는 정확하지 않다.




상보 필터(상호보완 필터/Complementary filter) :
-가속도 센서는 고주파 영역의 노이즈에 취약하기에 저역 필터를, 자이로스코프는 저주파 영역에서 드리프트 현상이 발생하므로 고역 필터를 통과시킨 후 그 값을 합쳐 사용

+) 위에서 이해한 가속도 센서, 자이로스코프의 문제와 고주파/저주파 영역 사이의 관계를 이해해보려고 했는데 이를 잘 설명하는 글을 찾지 못했다... 이 부분은 계측공학을 들어야 이해를 할 수 있지 않을까 싶다... 일단 문제 해결에서 상보 필터라는 것을 사용한다는 것만 알아간다.


-상보 필터를 적용한 roll, pitch를 보니 확실히 드리프트 현상이 없었고 가속도 센서의 값도 사용하므로 초기값에 관계없이 수평한 상태를 기준으로 한 현재의 기울기를 구할 수 있었다.

 

-상보 필터의 gain값에 따른 특성 및 변화 정리 예정


+) 아래는 참고한 블로그 중 몇 개를 추린 것이며 추후 내가 추가 공부할 때 도움이 될 거 같은 글이다.

https://mechaworld.tistory.com/11

 

가속도센서 및 자이로센서의 원리

자이로 센서와 가속도 센서는 실생활에서도 많이 쓰이는 센서가 되었습니다. 스마트폰에 장착되어 있는 자이로, 가속도 센서의 경우 사용자가 움직이는 모션을 감지하여 그에 맞는 다양한 반응

mechaworld.tistory.com


http://www.ntrexgo.com/archives/3930

 

[11호]왜 두 개의 센서를 융합하는가? | NTREXGO - 디바이스마트, 엔티렉스 컨텐츠 통합 사이트

[11호]왜 두 개의 센서를 융합하는가? Posted by 디바이스마트 매거진 on Saturday, February 25, 2012 · Leave a Comment  상보필터 Part 1.  왜 두 개의 센서를 융합하는가? 저자약력 : PinkWink. 로봇의 실제 구현

www.ntrexgo.com


https://sites.google.com/a/kookmin.ac.kr/mr-h/kudos/robot-study/complementary-filter-sangbo-pilteo

 

Mr.H - Complementary Filter(상보 필터)

Complementary Filter (상보 필터) 신호(Signal)란? - 시간에 따라 변화하는 DATA 주파수(Frequency)란? - 시간에 따라 변화하는 DATA의 1초 동안(주기적으로) 진동하는 횟수 필터(Filter)란? -시간에 따라 변화하는

sites.google.com

 

 

 

 







일단은 여기까지 IMU에 대해 간단한 공부와 실험을 했다.


여기까지 와서 드는 생각(질문)은 이랬다.

1. 자이로스코프의 드리프트 현상을 확인했다. 그런데 가속도 센서와 달리 자이로스코프는 격하거나 복잡한(여러 축으로 동시에) 회전을 하면 수평일 때 offset(오차?)가 발생했다. 이 또한 적분기에 의한 에러인지 궁금하다.

2. pid와 imu를 이용해 스마트폰 짐벌을 만드는 것은 뭔가 공부하기에 부족한 주제라는 생각이 들었다.


1은 구글링을 통해 찾아보고 없으면 카페나 지식in에 올려야겠다. 지금 대충 찾아봤는데 답을 못 찾아서 프로젝트를 진행하면서 계속 찾아봐야겠다.


2는 고민을 좀 하다가 주제를 바꾸는 것으로 결정했다. (스마트폰 짐벌 ---> 밸런싱 로봇)


 

 

 






이론 공부는 일단 여기까지만 하고 이제 센서를 ros에서 사용하기 위한 준비를 시작했다.


일단은 아두이노로 raw 데이터를 읽고 이를 ros의 imu관련 패키지를 통해 처리하려고 한다.


그래서 ros imu package로 구글링을 해서 패키지를 하나 찾았다.

 

http://wiki.ros.org/imu_tools?distro=noetic

 

imu_tools - ROS Wiki

melodic noetic   Show EOL distros:  EOL distros:   fuerte groovy hydro indigo jade kinetic lunar fuerte: Documentation generated on December 28, 2013 at 05:05 PMgroovy: Documentation generated on October 06, 2014 at 12:49 AMhydro: Documentation genera

wiki.ros.org

 

http://wiki.ros.org/imu_complementary_filter

 

imu_complementary_filter - ROS Wiki

melodic noetic   Show EOL distros:  EOL distros:   indigo jade kinetic lunar indigo: Documentation generated on June 09, 2019 at 02:23 AM (doc job).jade: Documentation generated on May 23, 2017 at 10:11 AM (doc job).kinetic: Documentation generated on

wiki.ros.org

+)위의 imu_tools를 설치하면 아래의 complementary_filter도 같이 설치된다.

 


패키지의 노드 설명을 보면 sensor_msgs/Imu 타입(linear_acceleration : vector3. angular_velocity : vector3만 포함하면 된다.)의 메시지를 subscribe 해서 orientation을 포함한 sensor_msgs/Imu 으로 publish 한다고 나와있다.


이를 바탕으로 데이터 흐름을 대충 그려봤다.


이를 토대로 rosserial을 이용한 아두이노 코드를 작성하기 시작했다.


여기서 처음에는 라이브러리를 안 쓰고 직접 raw data를 처리해서 rosserial로 보내려고 했다.


그 과정에서 아래 블로그를 포함해서 mpu6050과 그 raw data를 공부했다.

https://swiftcam.tistory.com/159

 

IMU MEMS 센서 MPU6050 살펴보기 2 - 가속도 센서

지난 번에 MPU6050의 자이로센서에 대해 살펴보고 노이즈 오차를 측정해보았다. 오늘은 MPU6050의 가속도 센서를 살펴보자. IMU MEMS 자이로 센서, 가속도 센서의 특징 및 각도 계산에 대해서는 아래

swiftcam.tistory.com



하지만 회로와 코딩 관련된 부분이 어렵기도 했고 단위와 관련된 내용을 찾을 수가 없어서 아래 mpu6050_light 라이브러리를 사용하기로 했다.

 

 

https://github.com/rfetick/MPU6050_light

 

GitHub - rfetick/MPU6050_light: Lightweight, fast and simple library to communicate with the MPU6050

Lightweight, fast and simple library to communicate with the MPU6050 - GitHub - rfetick/MPU6050_light: Lightweight, fast and simple library to communicate with the MPU6050

github.com

 

 

mpu6050_light를 사용해 얻은 가속도와 각속도는 각각 g와 deg/s으로 단위를 공식 문서에서 확인할 수 있었다.

 

 

sensor_msgs/Imu는 가속도와 각속도를 m/s^2과 rad/s로 받기 때문에 추가로 단위를 변환해야 했다.


아래 글의 rosserial publisher template을 바탕으로 코드를 작성했다.

https://www.intorobotics.com/template-for-a-ros-publisher-using-rosserial-on-arduino/

 

Template for a ROS Publisher Using rosserial on Arduino | Into Robotics

A few weeks ago I started writing a series of tutorials that ease the work of beginners in ROS. The first tutorial was about a template for a publisher node, the second tutorial was about a template for a subscriber node in ROS, and the third tutorial was

www.intorobotics.com

 

코드 자체는 컴파일도 성공했고 큰 문제가 없었다.

+) 위 코드 사진의 void setup에 mpu.begin()이 빠져 있다. 하지만 추가한다고 아래 문제가 해결되지는 않았다.

 


하지만 문제가 발생했다.

Message from device dropped: message larger than buffer 에러 발생


위 사진과 같은 에러가 계속 발생했다.


위 에러를 해결하려고 며칠 동안 계속 구글링 했다.

https://answers.ros.org/question/144056/imu-and-rosserial/

 

IMU and rosserial - ROS Answers: Open Source Q&A Forum

Hello, I'm using the arduino with rosserial and my code is the simplest one possible : #include #include #include ros::NodeHandle nh; sensor_msgs::Imu imu_msg; ros::Publisher pub_imu( "/imu", &imu_msg); char frameid[] = "/imu"; void setup() { Serial.begin(

answers.ros.org


https://answers.ros.org/question/91301/rosserial-fails-when-using-sensor_msgsimu/

 

rosserial fails when using sensor_msgs::Imu - ROS Answers: Open Source Q&A Forum

rosserial fails when using sensor_msgs::Imu edit I am attempting to send IMU messages to ROS from an Arduino and was making good progress until last night... I can send all sorts of primitive messages, and messages which contain other primitives, but for s

answers.ros.org


https://answers.ros.org/question/12782/rosserial_arduino-cant-send-a-sensor_msgsimu-msg/

 

rosserial_arduino can't send a sensor_msgs/Imu msg - ROS Answers: Open Source Q&A Forum

rosserial_arduino can't send a sensor_msgs/Imu msg edit Hi, I have a imu implemented with arduino that I'd like to connect to ros but I got stuck in the most simple thing, sending the Imu message. Sometimes it's it just hang sometimes I get an exception in

answers.ros.org


일단 내가 찾은(이해한) 해결책은 2가지였다.

1. 버퍼의 크기를 늘린다.

2. rosserial로는 그냥 array로 값만 보내고 이후 그 받은 값을 sensor_msgs/Imu 타입으로 바꿔서 publish 하는 노드를 하나 더 만든다.




그래도 원래 방법이 깔끔하다 생각해 1 방법을 찾아보고 시도했었다. 이때 아래 글을 중심으로 시도했었다.


https://answers.ros.org/question/73627/how-to-increase-rosserial-buffer-size/

 

how to increase rosserial buffer size - ROS Answers: Open Source Q&A Forum

how to increase rosserial buffer size edit I am trying to publish an odometry message with rosserial: nav_msgs::Odometry myOdom; ros::Publisher odom_pub("odom", &myOdom); .... odom_pub.publish(&myOdom); and it compiles fine, but I get an error that the mes

answers.ros.org


여러 방법을 해봤지만 실패했고 결국 2번 방법으로 바꾸기로 하고 아두이노 코드를 수정했다.



+) 글이 너무 길어져서 나눠서 작성한다.









========================================================================
정확한 정보 전달보단 공부 겸 기록에 초점을 둔 글입니다.
틀린 내용이 있을 수 있습니다.
틀린 내용이나 다른 문제가 있으면 댓글에 남겨주시면 감사하겠습니다. : )
========================================================================

 

반응형