[47호]스위스 아폴터(Affolter), SIMTOS 2018에서 혁신적인 기어 호빙 솔루션 발표
Affolter
스위스 아폴터(Affolter),
SIMTOS 2018에서 혁신적인 기어 호빙 솔루션 발표
한국은 스위스 기어 호빙 전문 기업인 Affolter Technologies(www.affoltergroup.ch)의 주요 시장으로, 한국 시장에 진출한 후 5년 만에 Affolter는 이미 전세계 연간 매출의 15%에 달하는 매출을 이 시장에서 창출하고 있다. 아울러 이 세계적인 기술 은 자사의 입지를 한층 강화하는 것을 목표로 삼고 있다. “매우 짧은 기간에, 우리는 다양한 시장에 영향을 미칠 수 있었습니다. 한국에서, 당사의 정밀 마이크로 기어 호빙 센터는 주로 방위산업, 치과 장비 및 로보틱스 등의 산업에서 수요가 많다”고 Affolter Technologies의 대표이사인 Vincent Affolter가 설명한다.
Affolter는 한국 시계 산업에도 서비스를 제공하고 있으며, 이 산업은 예로부터 스위스 자국 시장에서 중요한 부문이다. 또한, 고도로 전문화된 기업은 한국의 견실한 자동차 산업에서 매우 큰 잠재력을 보고 있다. “다수의 자동차 공급업체들이 최대 1.5mm의 모듈로 아주 높은 정밀도의 마이크로 웜 및 기어를 대량으로 제조해야 합니다. 이러한 초소형 기어와 웜 스크류의 다수가 자동차에 사용된다”고 Affolter의 한국 대리점인 LB Tech의 방화영 CEO는 설명한다. Affolter 엔지니어들이 개발한 최첨단 기술인 Worm Screw Power Skiving을 이용하여 제조업체는 기존의 웜 호빙보다 4배 더 빠른 속도인 단 6초 내에 초정밀 웜을 가공할 수 있다. “따라서 자동차 산업 제조업체는 생산성을 크게 향상시킬 수 있다”고 Vincent Affolter는 말한다.
주목 받는 AF90
2014년부터 SIMTOS 전시회에 참가해온 Affolter Technologies는 2018년 4월 3-7일 기간에 일산 Kintex(제2 전시장, 부스 07D590)에서 개최되는 SIMTOS에서 LB Tech의 협력 하에 자사의 혁신적인 기술과 제품을 선보일 예정이다. Affolter의 가장 작은 모델인 소형 기어용 전자동 AF90이 처음으로 부스에 전시된다. “AF90은 8축을 갖춘 첨단 CNC기어 호빙 센터로서, 우수한 생산성과 매우 빠른 절삭 속도를 갖추고있으며 스핀들 속도는 16,000 rpm에 달한다”고 Affolter는 설명한다. 최대 부품 직경은 30 mm이며, 최대 절삭 길이는 40 mm이다. AF90은피니언기어, 스플라인 및 기어휠의 절삭용으로 설계되어 있다.
품질 및 서비스 우선
호빙 머신에 대한 최고의 스위스 품질 기준 외에도, Affolter가 이처럼 빨리 성장할 수 있었던 것은 시장 네트워크와 애프터 서비스에 중점을두었기 때문이다. “우리는 현장에서 뛰어난 기술자를 보유 하고 있으며 최고의 고객 서비스 제공을 목표로 하고 있다”고 LB Tech의 방화영CEO는 말한다.
[47호]졸음운전 방지 시스템
2017 ICT 융합 프로젝트 공모전 참가상
졸음운전 방지 시스템
글 | 성결대학교 김성중, 오태식, 여규성, 이정희
1. 심사평
칩센 자동차 주행 시의 안전은 무엇보다 운전자와 타인의 생명과 직결되는 문제이고, 이를 기반으로 기획이 이루어진 것이라 생각됩니다. 이를 각 기술의 단계별로 검토가 이루어진 내용이 좋아 보입니다. 하지만, 실제 작품을 제작 및 시연이 이루어 지지 않았습니다. 차선 검출시에 중요한 요소인 소실점 등이 추출되지 않은 경우와 같은 변수가 전혀 고려되지 않아 예상되는 상황만으로 작품 개발이 이루어졌고, 눈 깜빡임 등과 같은 상수에 가까운 사항을 검증하지 않은 점이 아쉬움이 듭니다.
뉴티씨 낮은비용으로 졸음운전을 방지하려는 노력이 좋습니다. 사람들이 이 기능을 활용하여 안전운전을 할 수 있도록 되었으면 좋겠습니다. 많은 오류 등의 처리 등에 많은 개선점이 보이며, 앞으로 연구할 것이 많은 분야로 많은 업그레이드를 예상합니다.
위드로봇 완성이 된 작품인지 보고서만으론 판단하기 어렵습니다.
2. 작품 개요
졸음운전 방지 시스템
블랙박스에 졸음운전을 방지하는 기능을 더한다 .
3. 작품 설명
졸음운전으로 인한 사고는 잊을만하면 언론의 구설수에 오른다. 특히 큰 사고가 일어나기 쉬운 고속도로에서는 졸음운전으로 인한 사고가 많이 일어나고 있다. 고속도로는 도로 상태가 좋고 차량들의 속도가 빠르고 운전하는 시간이 길기 때문에 운전자가 졸기 쉽다.
사고가 나면 대형 사고일 확률이 높은 대형차량에는 졸음운전을 방지하는 여러 가지 시스템이 갖춰져서 출시되고 고급 승용차에는 최신 기술을 사용한 졸음운전 방지 시스템이 있어 옵션으로 선택할 수 있다.
하지만 저가형 승용차에는 최근에서야 졸음운전을 방지하는 LDWS가 달린 몇몇 기종이 출시되는 등 졸음운전에 대해 많이 취약하다.
그래서 고가의 차가 아니더라도 오늘날 차량에 대다수에 설치되는 블랙박스와 보편적 기기인 스마트폰을 가지고 그와 비슷한 시스템을 구현하기로 하였다.
옵션을 추가하지 않아도 졸음운전을 방지
아이작 IF520LD (블랙박스)
· 40만원대 블랙박스
· 기본 블랙박스 기능인 상시/주차/충격 녹화 등 여러 가지 기능 제공
· 전방 추돌 경보 시스템(FCWS : Forward Collision Warning System)
▶ 전방에 있는 차량과의 거리를 측정하고 일정거리 이하가 되면 알림을 계속 울리는 시스템
· 차선 이탈 경보 시스템(LDWS : Lane Departure Warning System)
▶ 블랙박스 영상에서 차선을 인식하여 사용자의 차량이 차선을 벗어나면 알림이 울리는 시스템
▶ 사용자의 차선 변경 여부를 차량의 방향지시등 점등을 통하여 알수있고 방향지시등이 점등 되었을 때는 알림을 울리지 않음
▶ 방향지시등 점등 여부를 알기 위하여 별도로 차량과의 Signal 케이블 필요
· 장점 : 여러 가지 고급 기능이 들어있는 블랙박스. 졸음운전뿐만 아니라 안전 운전에 도움이 되는 기능을 원하는 사용자에게 유용하다.
· 단점 : 제품 가격이 상당히(보급형 제품의 4배) 비싸다.
뷰메이트 DL330A (졸음 방지 알림기)
· 15만원대 제품
· 차량의 핸들/계기판에 설치하는 제품
· 시선 추적기술(Eye-Tracking)
▶ 사용자의 안면을 촬영하는 도중 시선을 추적하여 졸음상태를 감지하는 기술
· 졸음운전이 판단 되었을시에 소리로 알림을 준다.
· 장점
: 1) 차량의 상태를 확인하는 타 제품과는 다르게 직접 사용자의 상태를 확인하는 방식으로 졸음을 감지하여 정보의 신뢰도가 높다.
: 2) 차량에 설치하는 형태라서 관리가 쉽다.
· 단점 : 제품 가격이 비싸다.
3.1. 주요 동작 및 특징
사용한 도구
필요한 방법
3.2. 전체 시스템 구성
기본 기능
블랙박스(RaspberryPi)
· 차선 이탈 감지 시스템
· 차간 거리 측정 시스템
· 내부 온도 측정 센서
· 측정값을 Bluetooth를 이용하여 스마트폰에 전송
차량 ECU
· 차량의 정보를 블랙박스로 전송
스마트폰(Android Application)
· 눈꺼풀 개폐(눈 깜빡임) 감지 시스템
· 졸음 알림(스마트폰 H/W 사용)
· 블랙박스 환경설정 인터페이스
추가 기능
스마트폰(Android Application)
· 운전습관 케어(과거 주행 기록정보) 시스템
· 졸음여부를 서버에 전송
서버
· 인근에 있는 차량에 졸음운전 차량 유무를 전송
NFC 태그(스마트폰 거치대)
· 블랙박스와 스마트폰 간의 Bluetooth 페어링 보조
눈깜빡임 감지 시스템 구현 방법
0. 감지 과정
① : 얼굴 인식 ② : 눈 지역 추출 ③ : 눈 깜빡임 검출 ④ : 눈 깜빡임 분류
1. 얼굴 인식
사각형 안의 픽셀 강도의 합과 주변을 비교하여 결정. 정확하게 감지하기 위해 부스팅 알고리즘 – 아다부스트 알고리즘(조사필요)가 효과적이다.
2. 눈 영역 추출
눈 위치는 기하학적으로 발견한다. 얼굴을 h라 보았을 때 보통 눈은 0.2h ~ 0.6h 사이에 있고 평균적으로 0.4h에 존재한다.
3. 눈깜빡임 검출
눈은 정규화된 상호상관 방법(조사 필요)에 의해 검출된다.
4. 눈깜빡임 분류
자발적으로 눈을 깜빡인 것을 분류하기 위해 분석한다. 눈 깜빡임이 250밀리초 ~ 2초 사이일 때 자발적인 컨트롤로 간주한다.
눈깜빡임 검출
1. 준비사항
· 사용 기기 : 스마트폰 (SM-G930S 삼성 갤럭시S7)
· 프로그래밍 언어 : 자바
· 영상처리 api : OpenCV 3.0.0_android
2. 개요
위와 같은 사진에서, 얼굴과 눈을 검출하고 깜빡임을 체크
· 얼굴로서의 특징을 모두 가지고 있다.
· 처음부터 종료시까지 계속 눈을 감고 있지 않는다.
3. 설계과정
눈깜빡임 검출 구현
눈 깜빡임 검출 실험 Source Code
1. 흑백 변환
mJavaDetector.detectMultiScale(mGray, faces, 1.1, 2, 2,
// TODO: objdetect. CV_HAAR_SCALE_IMAGE
new Size(mAbsoluteFaceSize, mAbsoluteFaceSize), new Size());
3. 눈 영역 추출
Rect r = facesArray[i]:
eyearea_right = new Rect(r.x + r.width / 16,
(int) (r.y + (r.height / 4.5)),
(r.width – 2 + r.width / 16) / 2,
(int) (r.height / 3.0));
eyearea_left = new Rect (r.x + r.width / 16 + (r.width – 2 + r.width / 16) / 2,
(int) (r.y + (r,height / 4.5)),
(r.width – 2 + r.width / 16) / 2,
(int) (r.height / 3.0));
4. harr cascade를 이용하여 눈 검출
clasificator.detectMulti Scale(mROI, eyes, 1,15, 2,
Objdetect.CASCADE_FIND_BIGGEST_OBJECT
Objdetect .CASCADE_SCALE IMAGE, new Size(30, 30),
new Size());
눈의 위치 저장
lastEyes_L[lastEyes_num] = new Point(
(((matchLoc_tx_L.X + matchLoc_ty_L.x) / 2.0) – eyearea_left.x)/ facesArray[0] .width
(((matchLoc_tx_L.y + matchLoc_ty_L.y) / 2.0) – eyearea_left.y / facesArray[0] . height
}; // 눈 가운데의 좌표에서 두 영역 좌표를 깨고 얼굴 크기로 나누어서 상대좌표가 아닌 절대좌표로 만듬
lastEyes_R[ lastEyes_num] = new Point(
(((matchLoc_tx_R.x + matchLoc_ty_R.x) / 2.0) – ewearea_right.x )/ facesArray[0] .width ( (matchLoc_tx_R.y + matchLoc_ty_R.y) / 2.0 – eyearea_right.y / facesArray[0] . height
};
lastEyes_num++;
if(lastEyes_num == MAX_EYE_LEARN){
두 눈 모두 지정한 횟수 이상 높은 검출 했을 경우
insortionSort (lastEyes_L, 0);
insortionSort( lastEyes_R, 1);
}
삽입정렬로 정렬 후 오검출 제외
private void insortionSort (Point lastEyes[], int lef tRight) {
int i, j;
double ce;
for (i = 1; i <= NAX_EYE_LEARN -1; i++){
ce = lastEyes[i].x:
j =i – 1;
while( i >= 0){
if (lastEyes[J].x > ce){
lastEyes[j + 1].x = lastEyes[J].x:
j– ;
} else break;
lastEyes[] + 1].x = ce: }
// 삽입정렬
if (leftRight == 0) {
double tempX = 0, tempY = 0;
for (int k = 4; k< 16 : k++)
{ 오차라 판단하는데 0~3, 16~20을 제외하고 평균을 구함
Temp X = tempX + lastEyes[k].x;
Temp Y = tempy + lastEyes[k].y;
}
Temp X = Temp X / 12.0;
Temp Y = Temp Y/ 12.0;
eyeTemplete_L = new Point(temp X, temp Y);
abc_l= eyelenplete_L;
}
다음 프레임에서 옵티컬 플로우로 추적
Video, oalooptionlFlowPyrLK(tmp_last, frame, mat_last, tempMat, Status, err); //포티컬 플로우로 추적
Point[] parray2 = tempMat toArray():
리턴되어 저장될 변수
4. canny 변환
Imgproc.Canny(temp, temp, 50, 100);
5. 허프변환으로 기울기 계산
// 얼굴의 너비에 따라서 최소 선분 길이 지정
if (facesArray[0] .width > 700) line = 1;
else if (facesArray(0) ,width <700 && facesArray[0] .width > 650) Line = 0.92;
else if (facesArray(0).width <650 && facesArray(0).width > 600) Line = 0.84;
else if(facesArray[O).width <600 && facesArray[O).width > 550) Line = 0.76;
else if(facesArray(0) .width <550 && facesArray[0] .width > 500) Line =0.68;
else if (facesArray(0) .width <500 && facesArray[0] .width > 450) Line = 0.60;
else if(facesArray[0] .width <450 && facesArray[0] .width > 400) Line = 0.52;
else if(facesArray[O).width <400 && facesArray[0] .width > 350) Line = 0.44;
else if (facesArray[0] .width <350 && facesArray[0] .width > 300) Line = 0.36;
else if (facesArray[0] .width <300 && facesArray[0] .width > 250) Line = 0.28;
else if (facesArray[0] .width <250) line = 0.20;
Imgproc.HoughLines(temp, mLines, line, Math.PI/ 180.0,facesArray[0] .width/30);
기울기에 따라 다른 값 저장
private void insortionSort (Point lastEyes[], int lef tRight) {
int i, j;
double ce;
for (i = 1; i <= NAX_EYE_LEARN -1; i++){
ce = lastEyes[i].x:
j =i – 1;
while( i >= 0){
if (lastEyes[J].x > ce){
lastEyes[j + 1].x = lastEyes[J].x:
j– ;
} else break;
lastEyes[] + 1].x = ce: }
// 삽입정렬
if (leftRight == 0) {
double tempX = 0, tempY = 0;
for (int k = 4; k< 16 : k++)
{ 오차라 판단하는데 0~3, 16~20을 제외하고 평균을 구함
Temp X = tempX + lastEyes[k].x;
Temp Y = tempy + lastEyes[k].y;
}
Temp X = Temp X / 12.0;
Temp Y = Temp Y/ 12.0;
eyeTemplete_L = new Point(temp X, temp Y);
abc_l= eyelenplete_L;
}
눈 깜빡임 체크
if (blinkFlag == true){
if (nn > -9.5) blinkNotNum++; // 일정 수치 이상으로 올라가면 눈떴음 체크 변수 ++
if (blinkNotNum >= 3){ // 1.7초 안에 3프레임 이상 눈을 뜬게 발견될 경우
blinkFlag = false; // 눈떴음
blinkNotNum = 0; // 체크변수 = 0
blinkFlagTime = 0; // 시간 초기화
}
Long tmepTime = System. current Timellillis();
if (tmepTime – blinkFlagTime > 1700) { //1.7초 이상 눈 감고있으면
Vibrator vb=(Vibrator)getSystemService(VIBRATOR_SERVICE); // 진동을 줄 변수
vb. vibrate(100); // 진동
blinkNotNum = 2;
}
}
if(nn < -12.5 && blinkFlag == false) { // 일정수치 이하(눈감았다 판단)
blinkFlag = true; // 감았다고 판단
blinkFlagTime = System.ourrent Timelillis(); // 그때부터 시간을 잰다.
blinkNotNum = 0; 체크변수 = 0
}
눈 깜박임 검출 실험 결과
문제점 분석 및 해결방안
4. 단계별 제작 과정
4.1. 차선 인식
차선을 인식하기 위해서는 먼저 차선의 특징을 알 필요가 있다. 졸음운전이 일어나기 쉬운 고속도로에 존재하는 차선은 흰색/황색/청색이 있다. 이 3가지 종류의 차선을 특정하기 위하여 영상에서 흰색, 황색, 청색 영역을 추출한다. 차선의 종류는 ① : 흰색 차선(일반), ② : 황색 차선(중앙/끝), ③ : 청색 차선(버스전용) (*경부고속도로 상부) 이다.
흰색영역 추출 : 흰색영역을 추출하였을 때 차선이 아닌 다른 부분도 추출됨을 볼 수 있다.
차선 특정 : 색영역을 추출하여 얻어낸 데이터를 바탕으로 차선으로 추정되는 객체를 특정한다.
4.2. 차선 이탈 감지
차선 내부에서 잘못된 방향
운전자가 졸음으로 인하여 차량의 진행 방향이 차선과 동일하지 않을 경우. 차선 객체들의 연장선(빨강선)이 차량의 중심(파랑선)과 크게 어긋나 있어 이를 이용하여 차선 이탈을 판단할 수 있다.
차선을 밟은 경우
차량의 제어가 불가능하여 차선을 밟은 경우. 차선객체가 차량의 중심(파랑선)에 걸쳐 있음으로 이를 이용하여 차선 이탈을 판단할 수 있다.
4.3. 차선 검출
준비사항 :
사용 기기 : RaspberryPi 3, Logitech Webcam C270
프로그래밍 언어 : C++
영상처리 api : OpenCV 3.1.0
개요
풍경이 펼쳐지고 있을 때, 차선만을 검출하는 방법에 대하여 일반적인 도로의 모습에서 차선의 특징을 정의 한다.
· 차선의 색은 흰색, 노란색 등이고, 도로의 색과 큰 차이가 난다.
· 차선은 일정한 두께가 있다.
· 차선들은 하나의 소실점에서 만난다.
설계 과정
차선 검출 구현
1. Gray Scale 변환
· cv::cvtColor 함수를 사용하여 Gray Scale 변환
· 0. ~ 1. (float) scale로 변환하기 위해
· cv::Mat.convertTo 함수 사용
2. edge의 크기, 방향을 검출
· cv::Sobel 함수를 사용하여 x축, y축으로 미분
· cv::cartToPolar 함수에 x/y축으로 미분한 값을 넣어 edge의 크기(magnitude)와 방향(orientation)을 구한다.
3.edge가 각 구역에서 최대치가 되는 영역 검출
· magnitude의 정보가 담긴 객체의 값 중에 left < middle > right 가 되는 middle 값만 추출
4. 차선 후보 검출
· 영상의 아래쪽으로 갈수록 커지고 위로 갈수록 작아지는 최저 차선폭을 지정
· 같은 y값을 가지는 인접한 두 지점간 거리와 해당되는 y축의 최저 차선폭을 비교한다.
· 두 지점의 magnitude 값이 유사한지 검사한다.
· 위의 조건을 만족하였을 시에 두 지점의 orientation 값이 160 ~ 200도 차이가 나는지 비교한다.
· 모든 조건을 만족하면 두 지점의 중심점을 차선후보점으로 지정한다.
5. 선 검출
· cv::HoughLinesP 함수에 이전 연산의 결과로 나온 객체를 입력하여 직선 좌표값을 뽑아낸다.
6. 소실점 계산
· RANSAC 알고리즘을 이용하여 소실점을 찾아낸다.
· 소실점으로 향하는 직선만 차선으로 인정한다.
차선 검출 실험 Source Code
1. Gray Scale 변환
Mat gray = Mat(source.rows, source.cols, CV_BUC1);
cvt color( source, gray, CV-BGR2GRAY);
// 0. ~1. 그래미 스케일로 변환한다.
Mat gray32 = Mat::Oness source.ros, source.cols, CV-32FC1).
gray. convert Tof gray32, CV_32F, 1.01 255.0);
// 이미지를 부드럽게 만든다.
Mat smooth = Mat:; ones( source, rows, source.cols, CV-32FC1);
GaussianBlurgray32, smooth, Size(5,5), 2.0.2.0);
2. edge의 크기, 방향을 검출
Mat sobei x, sobel y:
Sobel( smooth, sobe X, CV_32F, 1, 0);
Sobel( smooth, sobe Y, CV_32F, 0, 1);
// Edge의 magnitude와 orientation을 계산한다.
Mat mag = Mat::ones( source.rows, source.cols, CV_32FC1);
Mat ori – Mat::ones( source.rows, source.cols, CV_32FC1);
cartToPolar( sobe IX, sobely, mag, ori);
3. 차선 후보 검출
{
int width = tmp[j].x – tmp[i].x;
if(lane_width)lo <= width && width <= lane_width_hi)
{
float mag_err = (tmp[j].mag – tmp[i].mag) / (tmp[j].mag + tmp[i].mag); //크기 차
float ori_err = DeltaRad(DeltaRad(tmp[j].ori, tmp[i].ori, M_Plf);// 방향 차
if((-mag_threshold < mag_err && mag_err < +mag_threshold) && (-ori_threshold < ori_err && ori_err < +ori_threshold))
{
int x_mid = (tmp[j].x + tmp[i].x / 2;
float mag_avg = (tmp[j].mag + tmp[i].mag) / 2.f;
// 평균을 낼 때 edge에 수직인 각을 pi/2를 더해 edge에 평행하게 바꾼다.
float ori_avg = (tmp[j].ori + tmp[i].ori / 2.f + M_Plf;
if(mag_avg <= 1.)
dst.at (h, x_mid) = 255;
//d[x_mid] = (mag_avg <= 1.) ? (int)(mag_avg+255) ; 255;
// For Debugging : 이미지 상에 Lane 후보들을 표시한다.
circle(source, Point(x_mid. h), 2, CV_RGB(0,0,255));
}
}
4. 선 검출
Mat lane = Mat::zeros(source, rows, source.cols, CV_BUC1);
//Lane의 후보가 될 점들을 찾는다.
LaneCandidate(mag, ori, lane);
//Lane 후보 점들을 저장할 공간 확보
vector(sLine> cand;
cand. reserve(1000);
//http://doce.opencv.org/2.4/modules/imgproc/doc/feature_detection.html
vector lines;
HoughLinesP(lane, lines, 1, CV_PI/180,5,2,10);
//Mat hought = Mat::zeros(source, rows, source.cols, CV_BUC1);
for(int i = 0; i < lines. size(); i++)
{
Point start = Point(lines[i][0], lines[i][1]);
Point end = Point(lines[i][2], lines[i][3]);
cand.push_back(sLine(start.x, start.y, end.x, end.y));
// For Debugging
line(source, start, end, CV_RGB(255,0,0),3,8);
line(hough, start, end, CV_RGB(255,255,255),3,8);
4. 소실점 찾기
Const int no_samples = 2;
if (data.size() < no_samples) {
return 0..
Vectors samples:
Vectors sPoint est imated_model: double max_cost = 0..
int max_iteration = (int )1 + log(1. – 0.99) log(1. – pow(0.5, no_samples)));
for (int i = 0; i<max_iteration: j++){<br=”"> if(i==0){
//처음 한 번은 미전 스탭의 모델로 알고리즘을 수행한다.
est imated_model = model:
else {
//1. Hypothesis
// 원본 데 미터 에서 임의로 N개의 샘플 데이터를 고른다.
Samples = get_samples (no_samples, data);
//이 데이터를 정상적인 데이터로 보고 모델 파라미터를 예측한다. estinated_model = Compute_model-parameter (samples):
// 2. Verification
//원본 데이터가 예측된 모델에 잘 맞는지 검사한다.
inliers.clear( ) double Cost = model-Verification(inliers, estimated_model, datadistance_threshold}}
만일 예측된 모델이 잘 맞는다면, 이 모델에 대한 유효한 데이터로 새로운 모델을 구한다.
if (max_cost < cost) {
max_cost = Costs;
model = compute_model-parameter (inliers):
}
}
return maX_Cost:
}
1. 차선 후보점 검출
2. 직선 검출
3. 소실점 계산, 최종 결과
4. 실제 Webcam을 사용한 실험 결과
- 직선 도로 상황
- 곡선 도로 상황
네트워크 통신
준비사항
사용 기기 : 스마트폰
프로그래밍 언어 : 자바
통신 방식 : FCM (FireBase Cloud Message)
개요
위와 같이 라즈베라파이와 안드로이드 스마트폰 사이의 통신을 조사하여 FCM이라는 클라우드 메시지 방식을 테스트해본다. FCM이란 메시지를 무료로 안정적으로 전송해줄 수 있는 메시지 전송 시스템이다.
설계과정
1. 안드로이드 app에 firebase를 추가한다. (패키지 이름, 앱 닉네임, 빈칸)
2. 자동적으로 google-services.json이 다운로드되면 프로젝트의 메니페스트가 있는 경로에 복사한다.
3. 서버에 프로젝트를 등록하고 sener ID와 server KEY를 얻는다. (Project>Settins>Cloud Messaging에서 체크
프로젝트수준 build.gradle 설정
앱 수준 build.gradle 설정
4. 프로젝트 수준과 앱 수준에서의 gradle을 전부 설정해준다.
5. 각 기기가 서버에 접속할 수 있게 토큰을 생성해준다.
6. 메시지 수신 시 이벤트로 노티피케이션과 진동을 준다.
7. 메시지 송신 시 서버로 메시지를 전송한다.
FCM 구현 및 소스코드
1. 토큰 생성
서버에서 해당 프로젝트의 어플 사용자임을 인증하고 토큰을 받는다. FirebaseInstanceId.getInstance().getToken() 메소드를 이용하여 해당 기기의 토큰을 생성한다. okhttp3의 Request 메소드를 이용하여 토큰을 서버에 전송한다.
// [START refresh_token]
@Override public
void onTokenRefresh () {
// Get updated Instance ID token.
String token = FirebaseInstanceId.getInstance().getToken();
// 생성등록된 토크를 개인 앱서버에 보내 저장해 두었다가 뭔가를 하고 싶으면 할 수 있도록 하다.
sendRegistrationToServer (token);
}
private void sendRegistrationToServer (String token) {
// Add custom implementation, as needed.
OkHttpClient client = new OkHttpClient ();
RequestBody body = new FormBody.Builder ()
.add(“Token”, token) .build();
//request Request request = new Request. Builder (0)
. url(“http://https://lastproject-c8250.firebaseio.com”) -post (body)
.build();
try {
client.newCall (request) .execute();
} catch (IOException e) {
e.printStackTrace();
}
}
2. 메시지 수신 시
// [START receive_message]
@Override
public void onMessageReceived (RemoteMessage remoteMessage) {
sendNotification (remoteMessage.getData().get (“message”)); vibrator vide;
vide = (vibrator) qetSystemService (Context.VIBRATOR SERVICE) ; vide.vibrate (1000);
}
private void sendNotification (String messageBody) {
Intent intent = new Intent (this, MainActivity.class); intent.addFlags (Intent. FLAG_ACTIVITY CLEAR TOP); PendingIntent pendingIntent = PendingIntent.getActivity (this, 0 /* Request code */, intent,
Pending Intent. FLAG_ONE_SHOT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri (RingtoneManager.TYPE_NOTIFICATION) ; NotificationCompat. Builder notificationBuilder = new NotificationCompat. Builder (this)
.setSmallIcon (R. mipmap.ic_launcher) .setContentTitle (“FCM Push Test”) .setContentText (messageBody) .setAutoCancel(true) .setSound (defaultSoundUri) .setContentIntent (pending Intent);
NotificationManager notificationManager =
(NotificationManager) getSystemService (Context. NOTIFICATION_SERVICE);
notificationManager.notify (0 /* ID of notification */, notificationBuilder.build(0);
3. 메시지 송신 시
databaseReference.메소드를 이용하여 서버의 데이터 베이스에 메시지를 쓴다.
final DatabaseReference database Reference = firebaseDatabase.getReference (); sendButton.setOnClickListener(new view.OnClickListener() {
@Override public void onClick(View v) { Chatpata chatData = new ChatData (editID.getText().toString(),
editText.getText().toString());
// 유저 이름과 메세지로 chatdata 만들기
databaseReference.child (“message”).push().setValue (chatData);
// 기본 database 하위 message라는 child에 chatdata를 list로 만들기
editText.setText (” “);
String a = editText.getText().toString(); if (a.equals(“”)) {
editText.setText(“”);
else
editText.setText (“”); listview.setTranscriptMode (AbsListView. TRANSCRIPT_MODE ALWAYS SCROLL);
// 메시지를 보낼때 제일 상단에 출력이 되게끔 한다.
}
});
databaseReference.child (“message”).addChildEventListener(new ChildEventListener() {
// message는 child의 이벤트를 수신합니다.
@Override public void onChildAdded (DataSnapshot data Snapshot, String s) {
Chatpata chatData = datasnapshot.getValue (ChatData.class);
} chatData를 가져오고
adapter.add (chatData.getUserName () + “:” + chatData.getMessage ());
// adapter에 추가합니다.
}
});
FirebaseMessaging.getInstance().subscribeToTopic (“news”); FirebaseInstance(d.getInstance().getToken();
FCM 실험 결과
제품 모형 제작
1. 준비 사항
제작 툴 : 스케치업, Creator K, 3DS Max
사용한 제작도구 : 3D 프린터
3D 프린터등을 이용하여 모형이나 외관 제작에 대해 조사한다. 여러 제작 툴을 사용해보고 가장 알맞은 제작 툴을 결정한다. 결정된 제작 툴로 테스트 모형을 출력해본다.
2. 제작 과정
1. 레이아웃 설계 및 제작 – STP
2. Creator K 호환 가능한 파일로 변환한다. – OBJ
3. Creator K를 통해 G-Code를 생성하고 프린팅을 시작한다.
3. 모형 제작 실험 결과
문제점 분석 및 해결방안
뭉침으로 인한 쓰레기 값 출력 : 내부 구조까지 정확한 설계를 해야한다고 판단
4. 진행상황
5. 향후 계획
라즈베리파이 – 고해상도에서 빠르게 검출할 수 있도록 최적화
스마트폰 – 눈 깜빡임 검출 부분 상세 조사
네트워크 – 라즈베리파이와 스마트폰 간의 블루투스 통신을 조사
외관 – 3ds max 프로그램을 더 공부하여 모형 제작
5. 참고문헌
옵티컬플로우 예제 : http://me10.sblo.jp/article/88289624.html
옵티컬플로우 함수 설명 : http://mycpp.blog.me/120110317337
opencv에서 옵티컬플로우 : http://blog.naver.com/hms4913/220126252051
옵티컬플로우 사용예제 : http://cafe.naver.com/opencv/38181
canny edge 기초설명 : http://carstart.tistory.com/188
자바에서 canny edge 사용 : http://stackoverflow.com/questions/24174868/edge-detection-using-opencv-canny
허프변환 기초설명 : http://blog.naver.com/dusrb2003/220290145675
허프변환 사용예제 : https://blog.zaven.co/opencv-advanced-android-development-edge-detection/
허프변환 사용예제 : http://stackoverflow.com/questions/7925698/android-opencv-drawing-hough-lines
설계/구현 과정 : http://blog.daum.net/pg365/200
환경 구축 : http://webnautes.tistory.com/916
언어간 함수변환 : http://lispro06.woweb.net/?mid=app&page=21
구글 firebase : https://console.firebase.google.com/
파이썬 채팅 앱 to firebase : https://corikachu.github.io/
안드로이드 UDP이용 메시지 전송예제 :
http://blog.naver.com/PostView.nhn?blogId=chandong83&logNo=220931445463&categoryNo=22&parentCategoryNo=0&viewDate=¤tPage=1&postListTopCurrentPage=1&from=postView
FCM으로 메시지 전송 구현 :
http://blog.naver.com/PostView.nhn?blogId=cosmosjs&logNo=220739141098&categoryNo=0&parentCategoryNo=56&viewDate=¤tPage=1&postListTopCurrentPage=1&from=search
안드로이드 FCM 샘플 : http://blog.naver.com/zic325/220719729251
Fire Base DataBase 기초 :
http://blog.naver.com/yoonhok_524/220918425133
스케치업 위키백과 : https://ko.wikipedia.org/wiki/%EC%8A%A4%EC%BC%80%EC%B9%98%EC%97%85
Creator K 사용자 가이드 http://print3dison.cafe24.com/board/free/read.html?no=816&board_no=1
3ds 맥스 위키백과 :
https://ko.wikipedia.org/wiki/3ds_%EB%A7%A5%EC%8A%A4
눈 깜빡임 관련 알고리즘 :
http://link.springer.com/article/10.1007/s10209-011-0256-6
안드로이드 눈깜빡임 감지 :
http://romanhosek.cz/android-eye-detection-and-tracking-with-opencv/
[47호]Pololu Dual G2 High-Power Motor Drivers for Raspberry Pi 제품군 출시
Pololu
라즈베리파이 확장 보드로 사용 가능한
Pololu Dual G2 High-Power Motor Drivers for
Raspberry Pi 제품군 출시
미국 모터 드라이버 모듈 전문 제조기업 Pololu에서 라즈베리파이 확장 보드로 사용 가능한 새로운 Dual G2 High-Power Motor Drivers for Raspberry Pi 제품군을 선보였다.
이 제품은 2개의 대형 브러시 DC 모터를 구동하도록 설계된 듀얼 MOSFET H 브리지를 특징으로 하는 라즈베리파이용 애드온 보드로, 모든 Raspberry Pi 3 B, B+ 에 장착할 수 있도록 설계되었다.
이 보드에는 5V, 2.5A 스위칭 스텝 다운 레귤레이터가 내장되어 있어 라즈베리파이에 전원을 공급할 수 있으며, 단일 전원 공급 장치로도 작동이 가능하다. 기본적으로 6개의 GPIO 핀을 사용하여 모터 드라이버를 제어하지만, 기본 설정이 편리하지 않을 경우 사용자가 핀 매핑을 변경할 수 있다. 4가지 버전 중에서 프로젝트에 적합한 작동 전압 범위와 출력 전류 기능을 갖춘 버전을 선택할 수 있다.
모터 작동 표시 LED는 모터가 연결되어 있지 않더라도 어떻게 출력이 되고 있는지 확인할 수 있어 편리하다. Raspberry Pi를 위한 Python 라이브러리를 제공해 쉽게 사용할 수 있도록 편의성에 초점을 맞췄다. Arduino와는 달리 Raspberry Pi에는 아날로그 입력이 없어 전류 감지를 쉽게 할 수 없었지만, 이 보드는 외부 ADC를 추가하거나 전류 감지 피드백을 사용할 수 있게 유연성을 더욱 높여 고급 사용자도 환영할만하다.
4가지 버전 모두 최소 작동 전압은 6.5V이며, 최대 작동 전압은 상세 사양에서 확인 가능하다. 디바이스마트(http://www.deveicemart.co.kr) 에서 자세한 정보를 확인할 수 있으며 구입 가능하다.
www.pololu.com
[47호]독거노인을 위한 안전 경보 시스템
2017 ICT 융합 프로젝트 공모전 참가상
독거노인을 위한 안전 경보 시스템
글 | 동아대학교 허수종, 유창희
1. 심사평
칩센 작품의 개발 의도는 대략 이해할 수 있습니다만, 구체적으로 어떤 시나리오에 따라 동작하는지에 대해 명확히 파악이 되지 않습니다. 제품의 개발 의도와 같은 서비스를 각 지자체 등에서 충분히 고려하고 있어 아이템의 의도나 사용성은 충분한 분위기가 만들어져 있으나, 이를 실제로 적용할 때 완성도를 떠나 구체적인 시나리오가 필요한 작품입니다. PIR 센서의 동작 감지 범위등과 같은 특성과 감지 주파수(감도)등에 대한 기술적 부분을 먼저 이해하여, 이를 효율적으로 사용할수 있는 것에 대한 내용이 없고, 또한 시스템 전체 동작 시나리오가 부족합니다. 이러한 부분이 보고서를 통해 이해하기에는 쉽지 않습니다.
뉴티씨 요즘 고독사도 증가하고 있고, 이웃나라에서는 벌써 사회적 문제가 된 지 오래다. 우리나라도 조만간 독거노인이 매우 늘어나게 되는 데, 노인들의 안전은 우리 자신의 문제가 되가고 있다. 따라서 이 아이템은 매우 중요한 아이템으로 보인다. 다만, 센서의 단순화로 감지할 수 있는 내용이 제한되므로, 좀 더 많은 종류의 여러 가지 센서를 사용하여 접근하였으면 좋았을 것이다. 앞으로 관심을 가지고 좀 더 다양하고 실질적인 내용으로 거듭나기를 기대해 본다.
위드로봇 고령화 시대에 걸맞는 주제입니다. 실용성이나 작품의 완성도는 높습니다만, PIR 센서 이외에 추가 센서를 활용하여 이상 징후를 좀 더 명확하게 알 수 있는 부분이 아쉽습니다.
2. 작품요약
독거노인의 수가 증가하는 추세인 요즘 독거사와 같은 문제가 사회 문제로 대두되고 있습니다. 독거노인의 안전을 위한 시스템으로 인체 감지센서(PIR Sensor)를 이용해 독거노인의 생활 패턴을 파악하고 파악한 데이터를 통해 평소와 다른 이상 부분이 감지 및 발생될 경우 부저와 LED를 이용해 장거리 무선 통신을 통해 주위 이웃에게 알리고 미리 지정해 놓은 가족의 휴대폰 애플리케이션을 이용해 진동과 토스트 메시지를 사용함으로써 신속한 경보를 알리는 시스템입니다.
3. 작품 개요
3.1. 선정 배경 및 목적
노인 고독사가 사회적으로 큰 문제가 되고 있다. 보건복지부에 따르면 2015년 기준 독거노인은 138만명을 넘어섰다. 이 가운데 고독사 위험군의 노인이 30만명 정도 된다고 알려졌다. 2015년 기준 통계이므로, 2017년 3월인 지금은 그 수가 더 늘어났으리라 예상된다.
홀로 쓸쓸히 죽음을 맞이하는 노인 수도 한 해 1,000명을 넘어선다고 밝혀졌다. 갈수록 1인 가구가 늘고 고령화 속도가 빨라지면서 고령자 1인 가구도 더욱 많아지고 있다. 그만큼 노인 고독사도 더욱 증가할 것으로 보인다.
정부에서 고독사 통계를 낼 때, 고독사 대신 무연고 사망자 수로 통계를 파악하고 있고, 2013년의 명백한 고독사는 1717건이다. 고독사 가운데 일부는 유족에게 시신이 인계되므로 고독사는 무연고 사망자수보다 훨씬 많을 것으로 예상된다. 명백한 수치로만 통계를 내도 5시간마다 한명씩 아무도 모르게 죽고 있는 것이다. 그런데 고독사에 대한 대책은 자발적 참여자를 받아 독거노인 5~10명을 한 집에 모여 살게 하는 노인 공동생활가정을 운영하는 것, 주기적으로 봉사 활동자가 방문하는 것, 상담을 늘리는 것 정도로 문제의 규모에 비해 작은 편이다.
우리나라는 현재 고령화가 급속히 진행 중이다. 전문가들에 따르면, 10년 후 65세 이상 1인 가구가 현재보다 2배로 늘고 고령자 1인 가구도 전체 3분의 1수준에 육박할 것으로 전망하고 있다. 노인 고독사는 누구든지 처할 수 있는 문제이다. 그전까지는 생각하지 못했던 부분이지만, 작품을 계획하는 과정에서 조사를 하면서 문제의 심각성이 예상보다 크다는 점을 깨달았다. 고독사는 인간의 존엄성을 훼손하는 비극적인 사건이다. 독거노인 비중의 증가에 따른 고독사 문제를 해결하는데 도움이 되고자 해당 아이디어를 구상하였다.
3.2. 아이디어 대상
1. 독거노인
2. 출장이나 여행이 잦은 집
아이디어를 통해 집안에 외부 침입자의 유무를 파악할 수 있다.
4. 작품 설명
4.1. 주요 동작 및 특징
4.1.1. PIR 센서
PIR 센서는 인간의 몸에서 나오는 적외선을 감지했을 때 작동한다. 주로 3V-12V에서 작동하고 적외선을 전압의 형태로 변환시켜서 출력 전압은 High일 경우 3.3V의 출력을 Low 일 경우 0V의 출력을 발생한다.
감지 거리는 최대 7m, 140˚의 거리를 감지 할 수 있다.
4.1.2.블루투스
블루투스의 무선 시스템은 ISM 주파수 대역인 2400 ~ 2483.5MHz를 사용한다. 블루투스는 저렴한 가격에 저전력(100mW)으로 사용할 수 있다는 점이 장점이다. 블루투스는 주파수 대역을 나누기 때문에 데이터 전송을 여러 주파수에 걸쳐서 분할해 보낼 수 있다. 그렇기 때문에 무선 전송에 따른 보안 위협에서도 상대적으로 안전하다. 블루투스 신호는 벽이나 가방 등을 통과해서 전송될 수 있으므로 배선이나 연결 상황을 육안으로 확인할 필요가 없고 장애물이 있어도 신호를 주고받을 수 있다. 주파수 특성도 전 방향으로 신호가 전송되므로 각 장치를 연결하기 위해 일정한 각도를 유지할 필요가 없어 사용하기에 편리하다. 마지막으로 무엇보다 전 세계 수많은 국가가 블루투스 표준 규격을 준수하기 때문에 세계 어느 곳에서나 같은 기술을 이용할 수 있다.
4.2. 전체 시스템 구성
전원을 공급한 후 안드로이드 스튜디오를 통해 제작된 애플리케이션과 블루투스 페어링(블루투스 외 비콘(Beacon)이나 와이파이를 이용한 통신방법도 가능) 과정을 거친 후 PIR 센서가 사람을 인식하고 있을 때는 동작하지 않는다. 그러나 사람이 일정 시간동안 감지되지 않을 경우에 작동 하게 되는데 부저와 LED를 이용해 주위에 알리고 블루투스를 이용하여 독거노인의 가족들에게 관련 메시지와 진동 기능을 통해 보다 신속 정확한 대처를 할 수 있도록 한다. 작동을 멈추기 위해서는 미리 설정되어있는 비밀번호를 입력하여 동작을 해제해야 한다. 추가적으로 애플리케이션에 긴급 전화 버튼을 추가하여 알림을 받는 동시에 바로 전화하여 조치를 취하게 할 수 있다.
4.3. 개발 환경
ATmega128를 이용한 하드웨어 설계 및 제작
안드로이드 스튜디오를 이용한 애플리케이션 제작
4.4. 기대효과
독거노인의 비중이 증가하고 따라서 연간 독거사 사망자의 수가 늘어나고 있는 현재 사회에서 보다 체계적인 안전 시스템을 통해 위급 상황 시 빠른 응급조치를 통해 생명을 구할 수 있다. 또한 노인들로 하여금 안전 시스템을 통한 심리적 안정감을 줄 수 있다.
5. 단계별 제작 과정
애플리케이션과 연동을 위해 ATmega128을 이용해 블루투스 개발 및 주위에 알릴 수 있는 수단으로 부저와 LED 추가
· 애플리케이션에 블루투스 기능 추가 및 페어링 환경 구축
· 블루투스 페어링 동작 유무 확인 및 메시지 송수신 여부 확인
· 외부 하드웨어 설계
6. 기타
6.1. 회로도
ATmega128, PIR Sensor, Bluetooth 모듈과 관련된 회로 라이브러리를 제공하지 않기 때문에 OrCAD를 이용해서 추가로 제작하여 회로를 구성.
6.2. OrCAD를 이용한 기판 배치도(PCB)
6.3. 애플리케이션
PIR 센서가 인식이 되면 LED와 부저가 켜지고 안드로이드 스튜디오를 통해 제작한 애플리케이션과의 블루투스 통신을 통해 AVR에서 문자를 전송하고 애플리케이션에서 문자를 수신하면 토스트 메시지와 진동이 울린다. 센서가 인식을 안 할 때 까지 계속해서 동작 하는 시스템이다.
6.4.소스 코드
AVR 소스
/*
* Reference about PIN Setting
* BlueTooth : PE1(RXD0/PDI), PE0(TXD0/PDO)
* PIR Sensor : PD0(SCL/INT0)
* LED : PB4-7
* Buzzer : PG3
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <string.h>
#include “ATmega128_v20.H”
#include “sub32.h”
ISR(TIMER3_OVF_vect) // 타이머 카운터 오버플로우 인터럽트
{
OCR3A =360; // 0~360까지 비교일치 후 오버플로우 발생, Port : PE3
}
int main()
{
MCU_initialize(); // MCU 초기화
Delay_ms(50);
LCD_initialize(); // LCD 초기화
Beep();
LCD_string(0×80,”16 Fall Semester”);
LCD_string(0xC0,”PROJECT “);
/* The first setting for state initialize */
UCSR0B |=(1<<TXEN0); // 송신 허용
UCSR0C |=(1<<UCSZ01)|(1<<UCSZ00); // Data rate 8bit
UBRR0H=0; UBRR0L=103; // Communication(signal) speed 9600bps
sei(); // 전역 인터럽트 허용
/* Setting for USART(about BlueTooth) */
Delay_ms(1000);
LCD_string(0×80,”SENSOR “);
LCD_string(0xC0,”COUNTER “);
while (1) password_input();
}
/*
* 사용된 함수들만 따로 헤더파일 정리
*/
#include “sub32.h”
int detect_counter=-1; // 센서 횟수 카운터 변수
unsigned char str[100];
int pw[5]={1,2,3,4};
int pw_check=0;
int num;
int str_num[20];
int enter=0;
//char *str=”abc123″;
unsigned int sum, ad_result;
unsigned int i =0;
unsigned int ADC6=0, ADC7=0;
int ADConvertor(char ch)
{
ADMUX = (ch&0x1F) | 0×40; // AVCC 사용
ADCSRA = (1<<ADEN)|(1<<ADSC)|(7<<ADPS0);
// ADC 허용, 프리스케일러 128
while((ADCSRA & 0×10)!= 0×10); //AD변환 과정이 끝났는지 확인
sum = ADCL+ADCH*256; // ADCW*256
return(ADC); // ADC의 값을 반환
}
void main_while()
{
ad_result = ADConvertor(6);
ADConvertor(6);
ADC6 = (sum/102.3*10);
LCD_command(0×80+12);
LCD_3d(ADC6); // LCD에 ADC6의 값을 출력
ADConvertor(7);
ADC7 = (sum/102.3*10); //in board ADC6 Position setting
LCD_command(0×80+8);
LCD_3d(ADC7); // LCD에 ADC7의 값을 출력
if(ADC6==100&ADC7==100) // 가변저항 2개의 값이 100 100 인지 확인
{
Delay_ms(70);
if(ADC7==100)
{
Delay_ms(1000);
state_on();
tx_char(’1′); // 문자 전송
}
}
else state_off();
}
void password_check(int input) // 비밀번호 확인 함수
{
num=input;
//LCD_command(0xC0+2);
//LCD_3d(num);
if(num==pw[pw_check]) // 미리 지정해둔 비밀번호와 일치 여부 확인
{
Beep();
pw_check++;
Delay_ms(100);
if(pw_check==4)
{
Beep();
Delay_ms(100);
Beep();
enter=1;
}
}
return enter;
}
void password_input() // 각각의 스위치에 숫자 지정
{
if(enter==0)
{
main_while();
switch(Key_input())
{
case 0x0E : password_check(1); // 1입력
break;
case 0x0D : password_check(2);// 2입력
break;
case 0x0B : password_check(3); // 3입력
break;
case 0×07 : password_check(4); // 4입력
break;
default : break;
}
}
else if(enter==1)
{
LCD_string(0×80,”LOGIN OK “);
LCD_string(0xC0,” “);
}
}
int counter(void)
{
++detect_counter; // 센서 감지 횟수 카운터
return detect_counter; // 카운터 값을 출력
}
void state_off(void) // PIR detect off
{
PORTB=0×00;
//PORTG=0×00;
//LCD_string(0×80,”SENSOR “);
}
void state_on(void) // PIR detect on
{
PORTB=0xf0; // LED 0000
//PORTG=0×08; // Buzzer
Beep();
//LCD_string(0×80,”SENSOR “);
LCD_command(0xC0+11);
counter();
LCD_3d(detect_counter);
}
void tx_char(unsigned char tx_data) // 한 문자 전송 함수
{
while((UCSR0A&0×20) == 0); // UDR0 레지스터가 빌 때까지 대기
UDR0 = tx_data; // UDR0 레지스터에 전송할 문자 입력
}
void tx_string(char *str) // 문자열 전송 함수
{
int i,j;
i=strlen(str); // 입력 받은 문자열의 길이를 변수 i로 지정
for(j=0;j<i;j++)
{
tx_char(*(str++));
/* 한 문자 전송 함수에 문자열의 길이를 파악 후 그 수치만큼 전송 */
}
}
6.5. 참고문헌
· 인체감지센서 참고 :http://blog.naver.com/yjhzzing4699?Redirect=Log&logNo=20161140929
· 블루투스 참고 : http://tip.daum.net/question/83517583
· 통계청 : http://kostat.go.kr/portal/korea/index.action
· 특허정보검색서비스 : www.kipris.or.kr
· 독거노인의 증가 추이와 독거노인 현황 : 한겨레 신문
[47호]전 연령대에 적합한 DIY 로봇키트 SUNFOUDER 원격제어 4족 보행 로봇
SUNFOUDER
전 연령대에 적합한 DIY 로봇키트
SUNFOUDER 원격제어 4족 보행 로봇
오픈 소스 로봇, 항공기 모델 및 스마트 기기등의 제품을 제조해 STEM 교육에 중점을 둔 기업 SUNFOUDER에서 DIY 원격제어 4족 보행 로봇키트를 출시했다.
아두이노, 서보 및 무선 모듈을 사용하는 방법뿐만 아니라 Arduino용 로봇 키트에는 원격 제어 기능이 있는 로봇을 만드는 데 필요한 모든 것이 포함되어 있다.
이 키트는 각 제품에 대해 간단하고 쉬운 학습을 위한 상세한 매뉴얼, 코드, 회로도, 드라이브 등 다운로드 관련 자료를 함께 제공하기 때문에 프로그래밍을 보다 쉽게 할 수 있다. DIY 4족 보행 로봇키트는 5mm 두께의 목재 플레이트로 제작되어 12개의 서보를 사용하여 4개의 다리를 유연하게 제어할 수 있다. DIY 로봇 키트를 제작해보는 과정 자체가 흥미로운 경험을 제공하므로 이 과정을 통해 자동화, 임베디드 시스템, 기계 엔지니어링, IoT 등 다양한 분야를 학습할 수 있다.
자신만의 DIY 로봇 키트를 제작해보고 싶다면 SUNFOUDER의 DIY 원격제어 4족 보행 로봇키트가 좋은 출발점이 될 수 있을 것이다. 제품에 대한 더 자세한 정보는 디바이스마트 홈페이지(http://www.devicemart.co.kr)에서 확인할 수 있다.
제품 구성
· 1 Set x 목재 플레이트
· 1 Set x 나사
· 2 x nRF24l01 모듈
· 2 x SunFounder 나노보드
· 1 x 리모컨
· 1 x 서보 컨트롤 보드
· 2 x 18650 배터리홀더
· 12 x SunFounder 서보
· 1 x USB 데이터케이블
· 1 x 와이어 하네스 튜브 (80cm)
· 1 x 리본(50cm)
· 1 x 보정 차트(calibration chart)
· 1 x 스크류드라이버
원격제어 4족보행 로봇 V2.0 Remote Control Crawling Quadruped Robot Model V2.0 [CZ0097] 제품 구매하러 가기