μμ κΈμμ μ΄λ‘ μ μΌλ‘ μ€λ€λ¦¬κΈ°λ₯Ό μ΄κΈ°λ λ°©λ²μ λν΄μ μμ±νμλ€.
[22' μ λν] μΆ©λΆκ³Όνμ λν (2) - μ€λ€λ¦¬κΈ°λ₯Ό μνμ μΌλ‘ μμ보μ
1. μ΄λ‘ μ λ°°κ²½ (1) νμ νν λ° λλ¦Όν νν 1) μ€λ€λ¦¬κΈ° μν©μμμ νμ νν μ€λ€λ¦¬κΈ° μν©μμ νμ ννμ μμ κ°λ€. μ νμ μ¬λ λͺ¨λμ μ€μ νλμ κ³λ‘ 보면 κ³ μΈλΆμμ μμ©νλ μ
mosw.tistory.com
κ·Έλ¦¬κ³ μ΄μ λ κ·Έ μ΄κΈ°λ λ°©λ²μ λ‘λ΄μ ν΅ν΄μ μ¦λͺ νκ³ μ νμλ€. μ¬λμ΄ μλ λ‘λ΄μΌλ‘ μ§νν κ°μ₯ ν° μ΄μ λ μ΄λ‘ μ μ΅μ μ κ°λλ₯Ό ꡬν μ μμ§λ§, κ·Έ κ°λκΉμ§ μ¬λμ κ·Όμ‘λ€μ΄ λ²νΈ μ μμκ³ , κ·Έ μ€νμ νλ λμ€μ μ€μ΄ νλ € λ€μΉλ μμ μμ λ¬Έμ κ° λ°μνμ¬ λ‘λ΄μΌλ‘ ꡬνν΄μΌκ² λ€λ μκ°μ λλμ± νκ² λμλ€.
λ‘λ΄μΌλ‘ ꡬννκΈ° μ μ λ¨Όμ μ€λ€λ¦¬κΈ° μν©μ κ°λ¨ν λͺ¨λΈλ‘ μ€μ νκ³ μ νμλ€. μ μ μΈ ννμ λμ΄μ λμ μΈ μν©μ λν΄ κ³ λ €ν΄μΌ νκΈ°μ, κΈ°λ³Έ λ§λλ‘ μμΈ‘μ μ μ μΈ ννμ μ΄λ£¨κ³ μλ μν©μμ μμνμλ€. κ°μ₯ κΈ°λ³ΈμΈ μ΅μ μ κ°λλ₯Ό μ μ§νλ€κ° μλμ μν΄ λλ €κ°λ€κ³ κ°μ νλ©΄, λ€μ μ΅μ μ κ°λλ₯Ό μ΄λ£¨κΈ° μν΄ λ°μ μμΌλ‘ 주좀거리며 κ°λλ₯Ό λ§μΆμ΄μΌ νλ€. λ°λλ‘ μλλ₯Ό λ΄κ° λκ³ μ€λ©΄ μμλ μ΅μ μ κ°λλ₯Ό μ΄λ£¨κΈ° μν΄ λ°μ λ€λ‘ 주좀거리며 λ€μ κ°λλ₯Ό λ§μΆ κ²μ΄λ€. κ²°κ΅, λ°©λ μμ μ΅μ μ κ°λλ₯Ό μ΄λ£¬ μν©μμ λΆκ°μ μΈ μμμ΄λ―λ‘, κ°λ μ μ§κ° κ°μ₯ μ€μνλ€.
μ΄λ¬ν μκ°μ νλ¦κ³Ό λ©μ»€λμ¦μ λ§λ λ‘λ΄ κ³΅νμ μμλ₯Ό μ°ΎκΈ° μμνλ€. νΉμ κ°μ λν΄ κ°λμ λ³νκ° μκΈ°λ©΄ μΆκ°μ μΈ νλμ νμ¬ λ€μ κ·Έ κ°λλ₯Ό λ§μΆμ΄μΌ νλ€. μ΄λ¬ν λͺ¨μ΅μ΄ μ§νλ©΄μ λν΄μ 90λ κ°λλ₯Ό μ΄λ£¨λ©° μ₯μΉκ° νλ€λ Έμ λ μλ€λ‘ μμ§μ¬ λ€μ 90λλ₯Ό λ§μΆλ μΈκ·Έμ¨μ΄ μ₯μΉμ μ μ¬νλ€λ μκ²¬μ΄ λμΆλμ΄ μ΄λ₯Ό λͺ¨λ°©νμ¬ λ§λ€μ΄λ³΄κ³ μ νμλ€.

1. κ°λ¨ν μ€λ€λ¦¬κΈ° λͺ¨λΈ μ μ
λ‘λ΄μΌλ‘ μ μνμ¬ μ€ννκΈ° μν΄μλ λ§€μ° λ³΅μ‘ν μ€λ€λ¦¬κΈ° μν©μ λν΄μ κ°μ’ λ³μλ₯Ό μ κ±°ν΄λκ°λ©° κ°λ¨ν λͺ¨λΈλ‘ λ§λ€ νμμ±μ λκΌλ€. λ°λΌμ κ°μ₯ κΈ°λ³Έμ΄ λλ μμ΄λμ΄λΆν° μμνμ¬ κ°λ¨ν μ€λ€λ¦¬κΈ° λͺ¨λΈμ μ μνκΈ° μμνλ€.

μμ κ°λ¨ν μμ 물체λμ κ°μ΄ μ§νλ©΄μμμ μΈκ·Έμ¨μ΄λ κ°μλ($\omega$)μ κ°κ°μλ($\alpha$)λ₯Ό μΈ‘μ νμ¬ κ°λμ λ³νλ₯Ό μΈμνλ€. μ΄λ₯Ό ν΅ν΄ λ°ν΄ λ±μ μ΄μ©ν¨μΌλ‘μ¨ κΈ°μΈμ΄μ§ λ°©ν₯ μͺ½μΌλ‘ 본체μ νλ¨ λΆλ₯Ό μ΄λμμΌ λ€μ μ§λ©΄κ³Ό μμ§μ μ μ§νλ€. μ΄λ μ΅μ μ κ°λλ₯Ό μ μ§νκΈ° μν΄μ μΈλ ₯μΌλ‘ μΈν΄ κ°λμ λ³νκ° μκ²Όμ λ, λ°μ 주좀거리며 μ΅μ μ κ°λλ₯Ό λ€μ μ μ§νλ μ μλ€μ λͺ¨μ΅κ³Όλ κ΅μ₯ν μ μ¬νλ€. μ΄μ κ°μ νΉμ§λ€μ ν λλ‘, μΈκ·Έμ¨μ΄λΌλ κ°λ μ λ‘λ΄ μ μμ ν΅μ¬ κ°λ μΌλ‘ μ μ νμλ€.

λ¨μνκ² μΈκ·Έμ¨μ΄λ₯Ό μ μ©νλ κ²λ§μΌλ‘λ μ€λ€λ¦¬κΈ° λͺ¨λΈμ μ λλ‘ κ΅¬ννκΈ°μλ νκ³κ° μμλ€. μΈκ·Έμ¨μ΄κ° μ μ§νλ κ°λλ μ§νλ©΄κ³Ό μμ§μΈ 90λμ΄μ§λ§, μ°λ¦¬κ° νμν λ‘λ΄μ μ½ 30λ κ·Όμ²μμλ κ°λλ₯Ό μ μ§νλ λͺ¨μ΅μ΄μλ€. λ°λΌμ νΉμ κ°μ μ μ§ν μ μλ λ³νλ μΈκ·Έμ¨μ΄μ κΈ°λ₯μ΄ νμνκ³ , κ²½μ¬λ©΄μμ μΈκ·Έμ¨μ΄λ₯Ό λλλ€λ©΄ μ΄λ€ μμ λͺ¨μ΅μ κ°μ§κ³ μμμ§μ λν΄μ μ¬κ³ μ€νμ μ§νν΄ λ³΄μλ€.
μ§νλ©΄μ λν΄μ $\theta$λ₯Ό μ΄λ£¨λ κ²½μ¬λ©΄μ μΈκ·Έμ¨μ΄λ₯Ό λμΌλ©΄, imu μΌμλ μ§κ΅¬ μ€μ¬μ λν΄μ μΈμμ νμ¬ λκ°μ΄ μ§νλ©΄μ λν΄μ 90λλ₯Ό μ΄λ£° κ²μ΄λΌλ κ²°λ‘ μ λ€ λ¬μλ€. μ΄λ λ€μ λ§νλ©΄ κ²½μ¬λ©΄μ μ ν΄μλ $90-\theta$μ κ°λλ₯Ό μ΄λ£° κ²μ΄λΌλ λ§κ³Ό κ°μλ€.
νμ§λ§ μ΄λ¬ν μν©μμ μλ‘ μ¬λΌκ°μΌ νλ μκ°κ³Ό μλλ‘ λ΄λ €κ°μ κ°λλ₯Ό λ§μΆλ μν©μ λ¬λλ€. μ§νλ©΄κ³Ό λ¬λ¦¬ μμλμ μμ§μμ μλ μ°¨μ΄λ λΆλͺ ν μ€λ ₯μ μν΄μ λ°μν κ²μ΄μκ³ , λ°λΌμ κ°λμ 물체μ μ€λ ₯μ κ³ λ €νμ¬ κ° λ°©ν₯μ λν λͺ¨ν° μλμ 보μ μ΄ νμνμλ€.

κ²½μ¬λ©΄μμμ μΈκ·Έμ¨μ΄μ μ½κ°μ λ³νλ₯Ό μ€λ€λ©΄ μμ κ·Έλ¦Όκ³Ό κ°μ λͺ¨μ΅μ΄ λλ κ²μ λ³Ό μ μλ€. κ²½μ¬λ©΄μμμ $mg\sin \theta$κ° μ₯λ ₯($T$)μΌλ‘, $mg\cos \theta$κ° μ€λ ₯($mg$)μΌλ‘ λμλλ€. λν κ²½μ¬λ©΄μ΄ μ§νλ©΄κ³Ό νννκ² λλ©΄μ κ²½μ¬κ°μ΄μλ $\theta$λ§νΌ μΈκ·Έμ¨μ΄κ° λλ λͺ¨μ΅μ΄ λλ€.
2.μλμ΄λ Έλ₯Ό μ΄μ©ν μΈκ·Έμ¨μ΄ κΈ°λ° μ€λ€λ¦¬κΈ° λ‘λ΄ μ μ - μμ½
μμμ μ»μ λͺ¨λΈμ λ§λ λ‘λ΄μ μλμ΄λ Έλ₯Ό μ΄μ©νμ¬ μ μμ μμνκ³ μ νμλ€. κ°μ₯ λ¨Όμ μ§νλ©΄μ μμ§μΌλ‘ μ μ§νλ κΈ°λ³Έννμ μΈκ·Έμ¨μ΄ μ μμ μ§ννλ€. λ‘λ΄μ ꡬμ±νλ μμλ‘ μ 체μ μΈ νλ μ, μλμ΄λ Έ UNO, λͺ¨ν°μ λͺ¨ν°λλΌμ΄λ², λ°°ν°λ¦¬ μ κ·Έλ¦¬κ³ κ°μλμ κ°κ°μλλ₯Ό μΈμνλ MPU6050(6μΆ κ°μλ μΌμ)λ₯Ό μ¬μ©νμλ€.
νΉν κ°μλλ₯Ό μΈμνλMPU6050μ λν΄ μ‘°μ¬, μ€νμ ν΅ν΄ X/Y/Z μΆμ λν κ°μλμ κ°κ°μλκ° μ΄λ€ ννλ‘ μ»μ΄μ§λμ§μ λν΄ νμΈνμλ€.

μΈμν κ°μ κ°κ³΅νκ³ λͺ¨ν°μ λͺ λ Ήνλ λ©μ»€λμ¦μ λν΄μ μκΈ° μ½κ³ μ²λ¦¬νκΈ° μ¬μ΄ ννλ‘ λ§λλ μμ μ΄ νμνλ€. μΌμμμ λ°μ xμΆ κ°μλ, yμΆ κ°μλ, zμΆ κ°μλ, xμΆ κ°κ°μλ, yμΆ κ°κ°μλ, zμΆ κ°κ°μλλ₯Ό μ΄μ©νμ¬, μ΄ κ°λ€μ μΉΌλ§νν°λ₯Ό μ΄μ©ν΄ 보μ ν λ€, μκΈ° μ½κ² νκΈ° μν΄μ Yaw, Pitch, Roll κ°μΌλ‘ λ°κΎΈλ κ²μ΄ λμ λλ€λ κ²μ μκ² λμ΄, ν΄λΉ κ°λ μ μ½λμ μ μ©νμ¬ λ³΄κ³ 1μ°¨ μ μν λ‘λ΄μ κ°λν΄ λ³΄μλ€..
κ·Έλ¬λ λ¨μν κ°λκ° κΈ°μΈμ΄μ§μ λ°λΌ λͺ¨ν°λ₯Ό κ°λνλ κ²λ§μΌλ‘λ μμͺ½μΌλ‘ μλ€ κ°λ€ ν λΏ, κ°λλ₯Ό μ μ§νμ§λ μμλ€. μ΄λ λ¨μν on/off ννμ μΆλ ₯λ°©μμ΄ λ¬Έμ λΌκ³ μκ°νμ¬ μ΄λ₯Ό ν΄κ²°ν μ μλ μ μ΄λ°©μμ λν΄ μ‘°μ¬νμλ€. κ·Έ κ²°κ³Ό κΈ°μΈμ΄μ§ θμ λΉλ‘ν λͺ¨ν° μΆλ ₯μ λͺ λ Ήνλ λΉλ‘ μ μ΄(Pμ μ΄), κ°μ’ μλ¬μ κΈκ²©ν λ³νμ λν΄ μμ μ±μ λμ΄λ λ―ΈλΆ μ μ΄(Iμ μ΄), μλ¬μ μ λΆ κ°μ λΉλ‘ν΄μ μμ€ν μ μ λ ₯μ μ£Όμ΄ μλ₯ μλ¬λ μ€μ΄λ μ λΆ μ μ΄(Dμ μ΄)λ₯Ό μ΄μ©νλ μ¦ PIDμ μ΄λ₯Ό μ¬μ©νκ³ μ νμλ€. PID μ μ΄μ λν μ΄ν΄λ₯Ό μν΄ λμ± μ‘°μ¬νκ³ κ³΅λΆνμ¬ μλμ΄λ Έ μ½λ©μ μ μ©νμ¬ 1μ°¨μ μΈ κΈ°λ³Έ λͺ¨λΈμ μ μν μ μμλ€.

μμλ³ μ±λ₯ λ―Έλ¬μ΄λ μ μ΄μμ λ±μ μν΄ λ²λ² 거리거λ μνλ μΆ μ΄μΈμ λ°©ν₯μΌλ‘ μμ§μ΄λ λ±μ λ¬Έμ μ μ΄ λ°μνμμ§λ§, μ 체μ μΌλ‘ μ§λ©΄μ λν΄ 90λλ₯Ό μ μ§νλ κ²μ κ΄μ°°ν μ μμλ€.
λ€μ λ¨κ³λ‘μ¨ μ€μ λ¬Άμ΄ μ₯λ ₯μ΄ μμ©νλ μνμμ κΈ°μΈκΈ°λ₯Ό μ μ§ν μ μλ μ€λ€λ¦¬κΈ° λ‘λ΄μ μ μνμλ€. 본체μ νλ μμ μ€κ³νμ¬ μν¬λ¦΄ κ°κ³΅μ ν΅ν΄ μλ‘μ΄ νλ μμ ν΅ν΄ λμ± μ ν©ν ννλ‘ λ°μ μμΌ°λ€.

μ μ΄μμ λ± μ½λμ μμ μ μ§ννμ¬ μμ λ§μ°¬κ°μ§λ‘ μ½κ°μ λ²λ² κ±°λ¦Όμ κ°μ§μ§λ§ μνλ νΉμ κ°λλ₯Ό μ μ§νλ €λ κ²½ν₯μ±μ λμ κ΄μ°°ν μ μμλ€. κ°μ λͺ¨λΈμ λ κ° λ§λ€μ΄ κ°λμ λν λΆμ, λ°λμ λν λΆμμ μ§ννκ³ μ νμμΌλ, μ°κ΅¬κΈ°κ° λΆμ‘± λ¬Έμ λ‘ μΈνμ¬ ν₯ν νꡬ κ³νμΌλ‘ μ ννμλ€.
// PID μ μ΄μ© λ³μ μ μΈ
double kp = 2.8;
double ki = 0.5;
double kd = 15;
// κΈ°μΈμΌ κ°λ μ ν
double originalSetpoint = 250;
double setpoint = originalSetpoint;
void loop(){
pid.Compute(); // 루νλ₯Ό λλ©΄μ pid κ°μ μ
λ°μ΄νΈν©λλ€
motorController.move(output, MIN_ABS_SPEED); // pid μ°μ°μΌλ‘ λμ¨ output κ°μ motorControllerλ‘ μ μ‘
// μΌμλ₯Ό ν΅ν΄ ꡬν Yaw, Pitch, Roll κ°μ Serial Monitorμ νμν©λλ€
Serial.print("ypr\t");
Serial.print(ypr[0] * 180/M_PI);
Serial.print("\t");
Serial.print(ypr[1] * 180/M_PI);
Serial.print("\t");
Serial.println(ypr[2] * 180/M_PI);
#endif
// PID μ μ΄λ₯Ό νκΈ° μν΄ input λ³μμ Pitch κ°μ λ£μ΅λλ€
input = ypr[1] * 180/M_PI + 180;
}
λν μ μ΄λ κΈμ μ 체 μ½λμ΄λ€.
// PID μ μ΄, λͺ¨ν° μ μ΄, MPU6050μΌμ κ°μ λ°κΈ° μν μ μΈλ¬Έ
#include <PID_v1.h>
#include <LMotorController.h>
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif
#define OUTPUT_TEAPOT 1 // Processingμ ν΅ν΄ MPU6050 μΌμλ₯Ό Visualize νκ³ μΆμ κ²½μ° 1, μλλ©΄ 0μΌλ‘ μ μΈν©λλ€
#define MIN_ABS_SPEED 30 // λͺ¨ν°μ μ΅μ μλλ₯Ό μ€μ ν©λλ€. 0 ~ 255 κ° μ€ μ ν
#define OUTPUT_READABLE_YAWPITCHROLL // Yaw, Pitch, Roll κ°μ μ»κΈ° μν΄ μ μΈν©λλ€
#define INTERRUPT_PIN 2 // MPU6050 μΌμμ INT νμ΄ κ½νμλ λ²νΈλ₯Ό μ€μ ν©λλ€. λ³΄ν΅ 2λ²
#define LED_PIN 13 // Arudino Unoμ 13λ²ν LEDλ₯Ό λμ μ€μ λ°μ§κ±°λ¦¬κ² νλ €κ³ μ μΈν©λλ€
//MPU κ°μ²΄λ₯Ό μ μΈν©λλ€
MPU6050 mpu;
// MPU control/status vars
bool blinkState = false; // LEDλ₯Ό λ°μ§κ±°λ¦¬κ² νκΈ° μν λ³μ
bool dmpReady = false; // set true if DMP init was successful
uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU
uint8_t devStatus; // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize; // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount; // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer
// MPU6050 μΌμλ₯Ό ν΅ν΄ μΏΌν°λμΈκ³Ό μ€μΌλ¬κ°, Yaw, Pitch, Roll κ°μ μ»κΈ° μν΄ μ μΈν©λλ€
// orientation/motion vars
Quaternion q; // [w, x, y, z] quaternion container
VectorInt16 aa; // [x, y, z] accel sensor measurements
VectorInt16 aaReal; // [x, y, z] gravity-free accel sensor measurements
VectorInt16 aaWorld; // [x, y, z] world-frame accel sensor measurements
VectorFloat gravity; // [x, y, z] gravity vector
float euler[3]; // [psi, theta, phi] Euler angle container
float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector
// ProcessingμΌλ‘ MPU6050 μΌμλ₯Ό Visualize νκΈ° μν λ³μ
// packet structure for InvenSense teapot demo
uint8_t teapotPacket[14] = { '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' };
// PID μ μ΄μ© λ³μ μ μΈ
double kp = 2.8;
double ki = 0.5;
double kd = 15;
// κΈ°μΈμΌ κ°λ μ ν
// μ κ° λ§λ λ°Έλ°μ±λ‘λ΄μλ 184.0λκ° κ°μ₯ μ΅μ μ ννκ°λμμ΅λλ€
// κ°λκ° 180λλ₯Ό κΈ°μ€μΌλ‘ +-λ₯Ό μ€μ ν΄μ£Όμλ©΄ λ©λλ€
double originalSetpoint = 250;
double setpoint = originalSetpoint;
double movingAngleOffset = 0.3;
// PID μ μ΄μ© input, output λ³μλ₯Ό μ μΈν©λλ€
double input, output;
// PIDκ°μ μ€μ ν΄μ€λ€
PID pid(&input, &output, &setpoint, kp, ki, kd, DIRECT);
// λͺ¨ν° μ μ΄μ© λ³μ μ μΈ
// EnA, EnBλ μλμ μ΄μ©(pwm), IN1,2,3,4λ λ°©ν₯μ μ΄μ© νμ
λλ€
int ENA = 10;
int IN1 = 12;
int IN2 = 6;
int IN3 = 9;
int IN4 = 8;
int ENB = 11;
// motorController κ°μ²΄ μμ±, 맨 λ νλΌλ―Έν° 1,1μ κ°κ° μ’μΈ‘, μ°μΈ‘λͺ¨ν°μ μ΅λμλ(%) μ
λλ€.
LMotorController motorController(ENA, IN1, IN2, ENB, IN3, IN4, 1, 1);
// === INTERRUPT DETECTION ROUTINE ===
volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high
void dmpDataReady() {
mpuInterrupt = true;
}
immediately
// initialize device
Serial.println(F("Initializing I2C devices..."));
mpu.initialize();
pinMode(INTERRUPT_PIN, INPUT);
// verify connection
Serial.println(F("Testing device connections..."));
Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
// load and configure the DMP
Serial.println(F("Initializing DMP..."));
devStatus = mpu.dmpInitialize();
// supply your own gyro offsets here, scaled for min sensitivity
mpu.setXGyroOffset(220);
mpu.setYGyroOffset(76);
mpu.setZGyroOffset(-85);
mpu.setZAccelOffset(1788); // 1688 factory default for my test chip
// devStatus κ°μ΄ 0 μ΄λ©΄ μ μμλ, 0μ΄ μλλ©΄ μ€μλ
// make sure it worked (returns 0 if so)
if (devStatus == 0){
// turn on the DMP, now that it's ready
Serial.println(F("Enabling DMP..."));
mpu.setDMPEnabled(true);
// enable Arduino interrupt detection
Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING);
mpuIntStatus = mpu.getIntStatus();
// set our DMP Ready flag so the main loop() function knows it's okay to use it
Serial.println(F("DMP ready! Waiting for first interrupt..."));
dmpReady = true;
// get expected DMP packet size for later comparison
packetSize = mpu.dmpGetFIFOPacketSize();
// MPU6050 μΌμκ° μ μμλνλ©΄ PID μ μ΄μ© μ½λλ₯Ό μ΄κΈ°νν©λλ€
pid.SetMode(AUTOMATIC);
pid.SetSampleTime(10);
pid.SetOutputLimits(-255, 255);
}
else{ // MPU6050 μΌμκ° μ€μλν κ²½μ°
// ERROR!
// 1 = initial memory load failed
// 2 = DMP configuration updates failed
// (if it's going to break, usually the code will be 1)
Serial.print(F("DMP Initialization failed (code "));
Serial.print(devStatus);
Serial.println(F(")"));
}
// λ‘λ΄μ΄ μλ μ€ 13λ² LEDλ₯Ό κΉλΉ‘거리기 μν΄ OUTPUTμΌλ‘ μ΄κΈ°νν©λλ€
pinMode(LED_PIN, OUTPUT);
}
void loop(){
// if programming failed, don't try to do anything
if (!dmpReady) return;
// wait for MPU interrupt or extra packet(s) available
while (!mpuInterrupt && fifoCount < packetSize){
//no mpu data - performing PID calculations and output to motors
pid.Compute(); // 루νλ₯Ό λλ©΄μ pid κ°μ μ
λ°μ΄νΈν©λλ€
motorController.move(output, MIN_ABS_SPEED); // pid μ°μ°μΌλ‘ λμ¨ output κ°μ motorControllerλ‘ μ μ‘
}
// reset interrupt flag and get INT_STATUS byte
mpuInterrupt = false;
mpuIntStatus = mpu.getIntStatus();
// get current FIFO count
fifoCount = mpu.getFIFOCount();
// MPU6050 μΌμκ° μ μμλνλ κ²½μ°μλ§ PIDμ μ΄λ₯Ό ν΄μΌνλ―λ‘ μλμ κ°μ΄ if-elseλ¬Έμ μμ±ν©λλ€
// check for overflow (this should never happen unless our code is too inefficient)
if ((mpuIntStatus & 0x10) || fifoCount == 1024){
// reset so we can continue cleanly
mpu.resetFIFO();
Serial.println(F("FIFO overflow!"));
}
// MPU6050 μΌμκ° μ μμλνλ κ²½μ°
else if (mpuIntStatus & 0x02){
// wait for correct available data length, should be a VERY short wait
while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
// read a packet from FIFO
mpu.getFIFOBytes(fifoBuffer, packetSize);
// track FIFO count here in case there is > 1 packet available
// (this lets us immediately read more without waiting for an interrupt)
fifoCount -= packetSize;
// display Euler angles in degrees
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
#ifdef OUTPUT_READABLE_YAWPITCHROLL // μΌμλ₯Ό ν΅ν΄ ꡬν Yaw, Pitch, Roll κ°μ Serial Monitorμ νμν©λλ€
Serial.print("ypr\t");
Serial.print(ypr[0] * 180/M_PI);
Serial.print("\t");
Serial.print(ypr[1] * 180/M_PI);
Serial.print("\t");
Serial.println(ypr[2] * 180/M_PI);
#endif
// PID μ μ΄λ₯Ό νκΈ° μν΄ input λ³μμ Pitch κ°μ λ£μ΅λλ€
input = ypr[1] * 180/M_PI + 180;
#ifdef OUTPUT_TEAPOT // ProcessingμΌλ‘ MPU6050μΌμμ μμ§μμ Visualize νκΈ° μν μ½λ
// display quaternion values in InvenSense Teapot demo format:
teapotPacket[2] = fifoBuffer[0];
teapotPacket[3] = fifoBuffer[1];
teapotPacket[4] = fifoBuffer[4];
teapotPacket[5] = fifoBuffer[5];
teapotPacket[6] = fifoBuffer[8];
teapotPacket[7] = fifoBuffer[9];
teapotPacket[8] = fifoBuffer[12];
teapotPacket[9] = fifoBuffer[13];
Serial.write(teapotPacket, 14);
teapotPacket[11]++; // packetCount, loops at 0xFF on purpose
#endif
}
}
λ€μ κΈμμλ κ°λ°μ λν΄μ μ‘°κΈ λ μμΈνκ² μμ±νκ³ μ νλ€.
κ΄λ ¨ μ½λλ€μ μ λ‘λν κΉν λ§ν¬λ λ€μκ³Ό κ°λ€.
https://github.com/MOSW626/Tug_of_War_Robot_Project_-2022-.git
GitHub - MOSW626/Tug_of_War_Robot_Project_-2022-
Contribute to MOSW626/Tug_of_War_Robot_Project_-2022- development by creating an account on GitHub.
github.com