제12회 임베디드SW 경진대회 웨어러블 디바이스 부문 최우수상

항공기 및 군사적용도로 제한적으로 사용되었던 HUD(Head Up Display)가 최근 전방주시로 인한 사고 감소를 위해 BMW를 비롯한 여러 고급 자동차에 탑재되어 출시되고 있다. 국내 업체로는 K9시리즈에 적용되어 출시되었다.

교통안전공단에 따르면 차량 계기판을 확인하기위해 짧게는 1초에서 길게는 3초까지 전방도로에서 시선을 뗀다고 한다.

시속 150km로 주행할 경우 80여미터를 전방을 주시하지 않고 운전하는 셈이다. 운전 중 전방주시 태만은 사고 발생확률을 23배, 사고시 중상을 입을 확률은 6배 이상높이며 운전조작 중 실수 가능성은 30여배 더 증가한다는 보고도 있다.

이처럼 내비게이션과 스마트폰 등의 보급 확산으로 운전자의 시인성이 감소함에 따라 사고 방지를 위해서도 HUD 기기에 대한 관심이 높아질 수밖에 없다. 2014년 5월 기준 국내 이륜차 등록대수는 2백만대를 넘어서고 있다.

하지만 이륜차 운전자를 위한 HUD시장은 국내는 전무한 실정이며 해외시장 역시 걸음마 수준이다.

또한 시간대별 구성비를 보면 야간시간대인 18시~24시에 가장 많은 사고가 발생하고 있다. 이는 일반 자동차에 비해 상대적으로 2차 사고 가능성이 높은 이륜차 운전자를 위한 최소한의 보호수단의 필요성을 잘 보여주는 부분이다.

따라서 본 프로젝트는 이륜차 운전자를 위하여 Android OS 기반 스마트폰과 AVR을 기반으로한 HUD(=HMD;Head Mounted Display), 음향장치를 통합하고 여기에 사고전파 및 운전자 보호 기능을 더한 통합 스마트 헬멧을 제작하는데 그 목적이 있다.

이번 글에서는 프로그램 개발환경과 각 함수별 기능에 대해 알아보겠다.

 

2.4. 개발환경
 

3. 프로그램 설명

3.1. 파일 구성
3.1.1. Hardware 파일 구성
 

3.1.2. Software 파일 구성
 

3.2. 함수별 기능
3.2.1. Hardware 함수별 기능

void UART1_Init()
// UART 초기화 함수 (UART1을 사용 설정 및 각 레지스터 세팅)
char rx_char()
// 블루투스 신호 한 문자 수신 함수
void rx_string()
// rx_char 를 이용한 블루투스 신호 문자열 수신 함수
void tx_char()
// 블루투스 신호 한 문자 송신 함수
void tx_string()
// tx_char 를 이용한 블루투스 신호 문자열 송신 함수
int adc()
// ADC 함수 (전압을 숫자로 변환하여 배터리 잔량을 확인)
ISR(USART1_RX_vect)
// 블루투스 신호가 수신되면 동작하는 Interrupt 함수
ISR(INT0_vect)
// 충격센서에 충격이 감지되면 동작하는 Interrupt 함수
switch(BUFFER[0]) { case ... }
// 블루투스 신호 BUFFER의 Header를 파악해 각 동작을 구현하는 함수
for(int i = 0; i < sizeof(BUFFER) - 1 ; i++)
// 블루투스 신호 BUFFER의 데이터를 복사하는 함수
if (ADResult 비교) { } else if (ADResult 비교) { } ...
// ad() 함수의 결과값인 ADResult의 값을 비교하여 배터리 잔량을 블루투스 신호로 송신하는 함수
strncpy(BUFFER, ‘’, sizeof(BUFFER))
// 문자열 복사 함수를 사용해 버퍼 BUFFER을 비우는 함수
u8g_DrawStr(&u8g, X, Y, STRING)
// 문자열 STRING을 OLED 화면의 (X,Y)에 그리는 함수
u8g_SetFont(&u8g, FONT)
// u8g_DrawStr의 폰트를 FONT로 설정하는 함수
u8g_InitSPI(&u8g, &u8g_dev_ssd1306_128x64_2x_sw_spi, PN, PN, PN, PN, U8G_PIN_NONE)
// OLED의 변수를 초기화 하고, OLED의 PIN과 연결 할 ATmega128의 PIN을 정의하는 함수
sei()
// Interrupt를 Enable하는 함수
EIMSK = 0b00000001;

// INT0를 개별 허용 (PD0를 이용)
EICRA = 0b00000010;
// INT0에 상승엣지 트리거가 발생 하면 Interrupt가 발생하도록 정의
SREG = 0x80;
// 모든 Interrupt를 허용
ADCSRA = 0b10000111;
// ADC를 Enable하고, 시스템 Clock을 분주하여 clk_ADC를 만들 때의 분주비를 32로 설정한다.
ADMUX = 0b11000010;
// ADC의 기준전압을 내부전압(2.56V)으로 설정하고, ADC의 입력PIN을 PF2(ADC2)로 설정한다.
u8g_FirstPage(&u8g)
// OLED 화면 출력 시작함을 나타내는 함수
u8g_NextPage(&u8g)
// OLED 화면 출력 끝남을 나타내는 함수

 

3.2.2. Software 함수별 기능 (핵심적인 함수들만 설명)

A_authority
Define.java // Debugging을 위한 변수들과 Application의 중요한 변수들을 한번에 관리
public final class OAuth { }
// TMAP API를 이용하기 위한 인증Key를 입력
ui
BluetoothActivity.java // Android Sample Code를 참고하였다.
public void sendMessage()
// 모든 Class에서 블루투스 신호를 송신하기 위해 사용하는 함수
// 정확하게 하기 위해선 BluetoothChatService의 wirte() 함수를 사용하는 것이 맞으나,
Application의 구조상 블루투스 신호를 송신하기 위해 Context가 필요해 Context가 없는
BluetoothChatService보다 BluetoothActivity가 더 적합하여 이 방법을 택하였다.
이 방법과 BluetoothChatService로 바로 블루투스 신호를 보내는 방법의 시간 차이는
100~200ms이므로 최종 구현에 있어서 무시할 수 있는 영향이다.
public void handleMessage() { case MESSAGE_READ : ... }
// 블루투스 신호를 수신하였을 때 사용되는 함수
// 위의 블루투스 신호 송신 함수와 같은 이유로 BluetoothChatService의
private class ConnectedThread() { public void run() ... } 함수를 택하지 않았다.
PathAlertActivity.java // 경로 탐색 Activity
private void setup(), private Location requestUpdatesFromProvider(), private void updateCooridiate()
// 현재의 위치를 파악하기 위한 함수
private class DestinationRequestTextWatcher { }
// 목적지 검색을 위해 타이핑을 할 때 Prograss Bar의 행동을 구현
private void getAuth()
// TMAP API를 이용하기 위한 인증Key로 로그인 하는 함수
private void startSearch()
// ‘경로찾기’ 버튼을 누를 때 작동하는 함수, Intent로 SearchPathActivity에 정보를 전달한다.
private void startSearchImmediate()
// ‘목적지로 경로찾기’ 버튼을 누를 때 작동하는 함수
private void searchTotalDestination()
// TMAP의 API를 이용한 자음 및 자동완성 검색 기능
SearchPathActivity.java // 경로 탐색 결과 Activity
private void setStartLocation()
// 현재 위치의 정보인 경도와 위도를 지역이름으로 바꾸는 함수
private void getIntentData()
// PathAlertActivity에서 Intent에 실어 보내준 데이터를 가져오는 함수
private void getRouteByMotorCycle()
// TMAP API를 이용하여 이륜차 경로를 검색하는 함수
private void startKMLParsing()
// private void getRouteByMotorCycle()의 결과값으로 받아온 *KML형식의 데이터를 XmlPullParser를 이용하여 
필요한 정보를 Parsing한다.
service
BluetoothChatService.java // Android Sample Code를 참고하였다.
public void write()
// BluetoothActivity에서 호출하는 블루투스 신호 송신 함수
private class ConnectedThread() { public void run() }
// 블루투스 신호를 수신하고 바로 BluetoothActivity에 신호를 넘겨준다.
BTSendService.java // ATmega128에 보내는 블루투스 신호에 데이터를 실어주는 핵심 Class
private long dist()
// 경도, 위도로 되어있는 두 좌표 사이의 거리 계산
private void BTsend()
// 블루투스 신호에 방향안내, 남은거리, 현재속도 데이터를 입력하여 송신
private void BTsendError()
// 블루투스 신호에 경로이탈 데이터를 입력하여 송신
private void SoundPlay()
// 음성안내의 내용을 선택하고 SoundService를 호출하는 함수
private void SoundPlay_delay()
// SoundService가 실행되고 있으면 다음 음성안내에 Delay를 적용해 음성안내가 겹치지 않도록 하는 함수
SoundService.java // 음성안내를 위한 Service
AlarmReceiver.java
public void onReceive()
// BTSendService를 언제든지 동작할 수 있도록 한다.
CallSMS_Receiver.java
public void onReceive()
// 문자수신과 전화수신시 블루투스 신호를 송신한다.
database
ContactBox.java
DesignatedContactBox.java (FavoriteBox.java와 RecentSearchPathBox.java도 동일한 함수 구조)
DBHelper.java
public void beginTransaction(), public void setTransactionSuccessful(), public void endTransaction()
// SQLiteDatabase에 데이터 입력 시작, 성공, 끝남을 알리는 함수
// DB에 바로 입력하는 것보다 Transaction을 이용하면 수행 속도가 훨씬 빠르다.
EntityDesignatedContactBox.java(EntityFavoriteBox.java와 EntityRecentSearchBox.java도 동일한 함수 구조)
entity
EntityContact.java ( EntityFavorite.java, EntityMovePathDetail.java,
EntityRecentSearch.java, EntitySimpleContact.java 모두 동일한 함수 구조)
EntityTotalSearch.java // 목적지 경로 검색시 자동완성 기능에 사용되는 Entity
tool
EntityParserHandler.java // 수신받은 KML 데이터를 Json에서 Entity Class 형태로 변환하는 Tool
Parsing_SearchPath.java // 경로 이탈 시 경로 재 요청 및 다시 새로운 KML 데이터를 Parsing하는 Class
RpnAlarmManager.java
public synchronized void startAlarm()
// AlarmReceiver를 지정된 시간을 주기로 지속적으로 호출하는 함수
// 결과적으로 BTSendService를 지속적으로 호출하게 하는 함수이다.
// 또한 BTSendService가 저장하지 못할 변수를 대신 가지고 저장을 해주는 함수
TurnTypeUtil.java // Parsing된 경로 방향안내를 경로 상세보기에 나타나는 한글로 된 경로 방향안내로 변환하는 Tool
TurnTypeUtilForBT.java // Parsing된 경로 방향안내를 ATmega128이 해석할 수 있는 경로 방향안내 데이터로 변환하는 Tool


3.3. 주요 함수의 흐름도
3.3.1. Hardware 주요 함수의 흐름도
 

3.3.2. Software 주요 함수의 흐름도
 

3.4. 기술적 차별성

표 1. 해외 제품들과 비교

[표1]은 출시예정인 제품들과 성능비교표이다. 일부 제품은 화려한 UI와 다양한 기능을 추가하였지만 이는 오히려 주행중 운전자의 집중을 흐트려 놓을 수 있는 단점으로 작용할 수 있다. 

본 제품은 운행 전 경로검색으로 제외하고 별다른 조작이 필요하지 않게 제작되었으며 단색으로 구성된 디스플레이를 채용하여 화려하지는 않지만 간결하고 가독성있는 구성을 갖추려 노력했다.

또한 기존 제품에서는 찾아볼수 없었던 충격센서를 이용한 사고감지/전파 기능을 추가하여 기술적 차별성을 추구했다. 이는 단순한 기능이 아니라 2차 사고 방지와 사고시 부상 가능성이 큰 이륜차 운전자의 생명과 직결되는 기능이다.

안내 정확도면에 있어 국내 가장 많은 사용자가 이용하는 TMAP의 API를 사용하여 안내 정확도를 향상시켰고 수많은 테스트와 디버깅을 통해 TMAP API 이용빈도를 줄여 기존 네비게이션 Application 대비 50% 이상 데이터 사용량을 감소시켰다.

구글이 경로검색을 지원하지 않는한 현재까지 국내에서 바로 사용할 수 있는 이륜차용 HUD 제품은 본 제품이 유일하다.

 

4. 응용 분야

차량 이외에 자전거, 인라인 스케이트 등 소형화, 경량화가 필수적인 부분에서 사용 가능하며, 충격 센서를 이용한 사고 감지 기능은 군사, 건설 등 안전이 중요시 되는 분야에 광범위하게 응용 할 수 있다.

 

글 : ACE_DK (김정수, 성정훈, 정성훈 / 단국대학교)
자료제공 : 임베디드소프트웨어·시스템산업협회

회원가입 후 이용바랍니다.
개의 댓글
0 / 400
댓글 정렬
BEST댓글
BEST 댓글 답글과 추천수를 합산하여 자동으로 노출됩니다.
댓글삭제
삭제한 댓글은 다시 복구할 수 없습니다.
그래도 삭제하시겠습니까?
댓글수정
댓글 수정은 작성 후 1분내에만 가능합니다.
/ 400
내 댓글 모음
저작권자 © 테크월드뉴스 무단전재 및 재배포 금지