KG_KAIROS/RobotProgramming

⚠️[KG_KAIROS] 로봇 센서 학습

projectlim 2024. 7. 22. 14:21
728x90
반응형
SMALL

24.07.22(월)

다시 돌아온 월요일.

저번주에는 라인트레이싱 RC카 제작과 로봇암을 제작하였습니다.

오늘은 각 센서들의 특성에 대해 배우고 적용법을 배워봅니다.

 

>>초음파 센서

아두이노 초음파센서(HC-SR04)사용 예제설명 : 네이버 블로그 (naver.com)

 

아두이노 초음파센서(HC-SR04)사용 예제설명

아두이노 초음파센서(HC-SR04)사용 예제 설명.   초음파센서란 초음파 센서는 약 20kHz이상의 높...

blog.naver.com

초음파 센서 작동원리.

울트라 소닉이라고 불리죠.

자동차 후방 센서에 가장 많이 쓰이죠 ㅎㅎ

 결국 같은 원리의 센서입니다.

 

자동차 후방 센서의 원리가 뭔가요? : 네이버 블로그 (naver.com)

 

자동차 후방 센서의 원리가 뭔가요?

자동차 후방 센서의 원리   자동차를 주차 할 때나 후진 할 때 자동차 뒤에 있는 물체나 어린이를 발...

blog.naver.com

 

 

>>적외선 센서

열감지 센서라고도 많이 불리죠!!

 

적외선 센서(IR Sensor) 원리 : 네이버 블로그 (naver.com)

 

적외선 센서(IR Sensor) 원리

사람의 눈으로 야간처럼 가시광선이 부족한 환경에서 물체를 판별하기란 매우 어려운 일이다. 그래서 어두...

blog.naver.com

가장 많이 쓰였던곳은??

저번 라인트레이싱 할때 검은색 선을 체크하는데IR센서를 사용하긴 했습니다.

 

하지만 우리 일상생활에서 가장 접하기 쉬웠던것은. 

코로나때 체온측정 카메라에 많이들 사용됩니다.

 

전북대, 신종 코로나 차단…중앙도서관에 '열감지 카메라' 설치 :: 공감언론 뉴시스통신사 :: (newsis.com)

 

전북대, 신종 코로나 차단…중앙도서관에 '열감지 카메라' 설치

[전주=뉴시스] 윤난슬 기자 = 전북대학교가 신종 코로나바이러스 감염증(우한 폐렴) 확산 방지를 위해 총력을 기울이고 있다.전북대는 교내 중앙도서관 로비 출입구에 출입자들의 체온을 측정하

www.newsis.com

 

>>거리측정센서

광삼각법 vs TOF방식

 

 

먼저 [광삼각법]

 

광삼각법 방식의 기본은 카메라와 레이저(광원), 오브젝트 사이의 삼각 구조인데요, 아래의 그림처럼 이 세가지 구성요소의 거리와 각을 이용하여 삼각형의 기본을 만들어 냅니다.

Line Laser가 오브젝트에 조사되고, 오브젝트 표면에 조사 된 레이저는 또 다시 카메라 센서로 반사되어 돌아오는데 이 빛의 각도에 의해 3D를 계산해 내는 방법입니다.

6. Laser triangulation_1 : 네이버 블로그 (naver.com)

 

6. Laser triangulation_1

안녕하세요~ '노마'입니다!즐거운 주말보내셨나요?아직 6월 중순인데 날씨가 엄청 더워졌더라구요! 다들 물...

blog.naver.com

 

다음 TOF방식

 

전 시간에 사용했던 ToF센서는 결국 레이저를 사용합니다.

ToF (Time of Flight)란? (2) - 동작원리, 장점,단점, 주요 Components (tistory.com)

 

ToF (Time of Flight)란? (2) - 동작원리, 장점,단점, 주요 Components

안녕하세요 지난번엔 ToF에 관해서 간략하게 정리해보았는데 이번 포스팅에서는 ToF 동작원리에 대해서 더 자세하게 정리해보겠습니다 :) ToF는 Time of Flight로 빛을 쏘아서 반사되어 오는 시간을

eunkyovely.tistory.com

 

time of flight는 결국 비행시간을 의미합니다.

 

 

 

초음파와 적외선 센서중에 뭘써야할까 고민했을때.

 

가장 큰 차이는 전력소모에 차이가있다.

초음파는 먼거리를 측정하기에 전력소모가 심하다. 하지만 적외선 센서는 근거리 측정에 유용하며 전력소모가 적다.

또한 환경차이가 존재하는데 초음파는 매질에 영향을 받는 반면 적외선센서는 반사율이 높은 물체에 영향을 많이 받습니다.  

 

 

VL53L0X센서랑 초음파센서를 이용해서 체크하기!!

이게 센싱..!

#include <Wire.h>
#include <Adafruit_VL53L0X.h>
#include <NewPing.h>

// VL53L0X 객체 생성
Adafruit_VL53L0X lox = Adafruit_VL53L0X();

// HC-SR04 핀 설정
#define TRIGGER_PIN 9
#define ECHO_PIN 10
#define MAX_DISTANCE 200  // 최대 거리 (센티미터 단위)

// 초음파 센서 객체 생성
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);

void setup() {
  Serial.begin(115200);
  Serial.println("Distance Measurement Test");

  // VL53L0X 초기화
  if (!lox.begin()) {
    Serial.println("Failed to find VL53L0X chip");
    while (1) {}
  }
  Serial.println("VL53L0X found!");
}

void loop() {
  // VL53L0X 거리 측정
  VL53L0X_RangingMeasurementData_t measure;
  lox.rangingTest(&measure, false);

  // VL53L0X 측정 값 출력
  if (measure.RangeStatus != 4) {
    Serial.print("VL53L0X Distance (mm): ");
    Serial.println(measure.RangeMilliMeter);
  } else {
    Serial.println("VL53L0X Out of range");
  }

  // HC-SR04 거리 측정
  delay(50);  // VL53L0X 측정 후 잠시 대기
  unsigned int uS = sonar.ping();  // 초음파 센서에서 거리 측정
  float distance_cm = uS / 58.0;    // 거리(cm) 계산

  // HC-SR04 측정 값 출력
  Serial.print("HC-SR04 Distance (cm): ");
  Serial.println(distance_cm);

  delay(500);  // 500ms 대기
}

결과값.

강사님이 보내주신 코드로 개별 체킹하는 코드도 공유해드리겠습니다.

 

 

#include "Adafruit_VL53L0X.h"

Adafruit_VL53L0X lox = Adafruit_VL53L0X();

void setup() {
  Serial.begin(115200);
  
  Serial.println("Adafruit VL53L0X test...");
  if (!lox.begin()) {
    Serial.println(F("Failed to boot VL53L0X"));
    while(1);
  }
  // power 
  Serial.println(F("VL53L0X test OK...")); 
}


void loop() {
  VL53L0X_RangingMeasurementData_t measure;
    
  Serial.print("Reading a measurement... ");
  lox.rangingTest(&measure, false); // pass in 'true' to get debug data printout!

  if (measure.RangeStatus != 4) {  // phase failures have incorrect data
    Serial.print("Distance (mm): "); Serial.println(measure.RangeMilliMeter);
  } else {
    Serial.println(" out of range ");
  }
    
  delay(100);
}

ToF센서

// defines pins numbers
const int trigPin = 3;
const int echoPin = 2;
// defines variables
long duration;
int distance;
int ledonoff(int value);
void setup() {
  pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
  pinMode(echoPin, INPUT); // Sets the echoPin as an Input
  Serial.begin(115200); // Starts the serial communication
}
void loop() {
  // Clears the trigPin
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  // Sets the trigPin on HIGH state for 10 micro seconds
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  // Reads the echoPin, returns the sound wave travel time in microseconds
  duration = pulseIn(echoPin, HIGH);
  // Calculating the distance
  distance = duration * 0.034 / 2;
  delay(200);
  // Prints the distance on the Serial Monitor
  //Serial.print("Distance(cm): ");
  Serial.println(distance);
  ledonoff(distance);
}
int ledonoff(int value){
  if(value > 200){
  Serial.print(value);
  Serial.println("light is on");
  }
  else {
  Serial.println("light is off");
  }
}

초음파센서 체킹

 

시리얼 플로터까지 체크확인.

위에 수치가튀는것은 비닐팩에 반사되서 천장인식해서 그렇습니다. 

 

 

이번엔 카메라센서~

import cv2
import sys

# 비디오 파일 열기
cap = cv2.VideoCapture(0)

if not cap.isOpened():
    print("Video open failed!")
    sys.exit()

# 배경 영상 등록
ret, back = cap.read()

if not ret:
    print("Background image registration failed!")
    sys.exit()

# 연산 속도를 높이기 위해 그레이스케일 영상으로 변환
back = cv2.cvtColor(back, cv2.COLOR_BGR2GRAY)

# 가우시안 블러로 노이즈 제거 (모폴로지, 열기, 닫기 연산도 가능)
back = cv2.GaussianBlur(back, (0, 0), 1.0)

# 비디오 매 프레임 처리
while True:
    ret, frame = cap.read()

    if not ret:
        break

    # 현재 프레임 영상 그레이스케일 변환
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    # 노이즈 제거
    gray = cv2.GaussianBlur(gray, (0, 0), 1.0)

    # 차영상 구하기 $ 이진화
    # absdiff는 차 영상에 절대값
    diff = cv2.absdiff(gray, back)
    # 차이가 30이상 255(흰색), 30보다 작으면 0(검정색)
    _, diff = cv2.threshold(diff, 127, 255, cv2.THRESH_BINARY)

    # 레이브링을 이용하여 바운딩 박스 표시
    cnt, _, stats, _ = cv2.connectedComponentsWithStats(diff)
    for i in range(1, cnt):
        print("detect", cnt)
        x, y, w, h, s = stats[i]

        if s < 100:
            continue

        cv2.rectangle(frame, (x, y, w, h), (0, 0, 255), 2)

    cv2.imshow("frame", frame)
    cv2.imshow("diff", diff)

    if cv2.waitKey(30) == 27:
        break
    back = gray.copy()

cap.release()
cv2.destroyAllWindows()

 

 

이번에는 부저울리기를 해볼겁니다. 통신을 통해서!!

import cv2
import sys
import serial
import time

ser = serial.Serial('COM5', 9600)
cap = cv2.VideoCapture(0)
if not cap.isOpened():
    print("Video open failed!")
    sys.exit()
    
ret, back = cap.read()
if not ret:
    print("Background image registration failed!")
    sys.exit()

back = cv2.cvtColor(back, cv2.COLOR_BGR2GRAY)
back = cv2.GaussianBlur(back, (0, 0), 1.0)

while True:
    ret, frame = cap.read()
    if not ret:
        break
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray, (0, 0), 1.0)

    diff = cv2.absdiff(gray, back)
    _, diff = cv2.threshold(diff, 127, 255, cv2.THRESH_BINARY)

    # 인식되는 갯수를 세기 위해서 cnt 개수를 연결
    cnt, _, stats, _ = cv2.connectedComponentsWithStats(diff)
    count = 0
    for i in range(1, cnt):
        x, y, w, h, s = stats[i]
        if s < 100:
            continue

        count += 1
        cv2.rectangle(frame, (x, y, w, h), (0, 0, 255), 2)

    if count >= 1:
        ser.write(b'1')
    else:
        ser.write(b'0')

    cv2.imshow("frame", frame)
    cv2.imshow("diff", diff)

    if cv2.waitKey(30) == 27:
        break
    back = gray.copy()

cap.release()
cv2.destroyAllWindows()
ser.close()

회로 만들어주시고 부저를 달아두면 가능합니다.

int buzzerPin = 8;
void setup() {
  pinMode(buzzerPin, OUTPUT);
  Serial.begin(9600);
}
void loop() {
  if (Serial.available() > 0) {
    char data = Serial.read();
    if (data == '1') {
      digitalWrite(buzzerPin, HIGH);
    } else if (data == '0') {
      digitalWrite(buzzerPin, LOW);
    }
  }
}

 

 

이걸 응용해서 로봇도 움직여봐야하는데...

 

일단 이번엔 자이로 센서

mpu6050입니다.

 

라이브러리는 mpu 6050 light 다운받아주시고

#include "Wire.h"
#include <MPU6050_light.h>

MPU6050 mpu(Wire);

unsigned long timer = 0;

void setup() {
  Serial.begin(115200);
  Wire.begin();
  
  byte status = mpu.begin();
  Serial.print(F("MPU6050 status: "));
  Serial.println(status);
  while(status!=0){ } // stop everything if could not connect to MPU6050
  
  Serial.println(F("Calculating offsets, do not move MPU6050"));
  delay(1000);
  mpu.calcOffsets(true,true); // gyro and accelero
  Serial.println("Done!\n");
  
}

void loop() {
  mpu.update();

  if(millis() - timer > 200){ // print data every second
    print_angle();
    timer = millis();
  }

}

void print_angle(){
  // Serial.print("X: ");
  Serial.print(mpu.getAccX());
    Serial.print("   ");
  // Serial.print("Y: ");
  Serial.print(mpu.getAccY());
    Serial.print("   ");
  // Serial.print("Z: ");
  Serial.println(mpu.getAccZ());
}

 

 

>>MEMS 자이로 센서.

코리올리 효과에 의해서 진행됨.

 

프랑스 수학자 Gaspard-Gustave de Coriolis의 이름을 딴 코리올리 효과는 지구의 자전으로 인해 지구 표면에서 움직이는 물체의 겉보기 편향을 설명하는 물리적 현상이며, 회전하는 기준 프레임에서 유체와 물체의 움직임에 영향을 미치기 때문에 기상학, 해양학 및 물리학에서 중요한 개념입니다.

코리올리 효과는 지구의 자전과 물체의 직선 운동의 조합에서 발생합니다. 지구가 자전할 때, 지구 표면의 다른 점들은 자전축으로부터의 거리에 따라 다른 속도로 움직입니다. 적도는 가장 높은 선형 속도를 경험하는 반면, 극지방은 선형 속도가 0입니다. 이러한 선형 속도의 차이는 코리올리 효과를 발생시킵니다.

 

코리올리 효과(Coriolis Effect) 의 뜻과 자연현상 : 네이버 블로그 (naver.com)

 

코리올리 효과(Coriolis Effect) 의 뜻과 자연현상

은빛해일입니다! 오늘은 코리올리 효과라는 것에 대해 설명을 드려볼까 합니다. 아주 흔하게 들어볼 수 있...

blog.naver.com

 

>>지자기센서

주변의 자기장을 감지하여 그 값을 전기 신호로 변환하는 센서.

 

>>GPS센서

 

>> 라이다 센서

ToF를 사용하여 주변인식하는것. 전 피드에서도 작성한 센서지만. 레이더 보다는 해상도가 좋지만 카메라보다는 좋지 않다.

 

레이저센서가 입사광을 쏘고 광센서로 반사광이 들어가는 시간의 차이가 거리에 해당된다.

 

 

 

라이다(LiDAR)의 원리 및 활용 : 네이버 블로그 (naver.com)

 

라이다(LiDAR)의 원리 및 활용

1. 개요 LiDAR란 Light Detection And Ranging 또는 Laser Imaging Detection And Ranging의 ...

blog.naver.com

참고하면 좋을듯 싶네여.

 

 

728x90
반응형
LIST