Skip to content

Seethrough_ProjectBlog

yeong-jpg edited this page Dec 4, 2017 · 92 revisions

시각장애인을 위한 버스도착안내 어플리케이션

씨스루 팀 | 윤지영, 이현지


목차

서론

  • 문제정의
  • 우리의 목표
  • 사용자 예상 조건

본론

  1. 적용한 기술
    1. GPS로 현재 위치 인식
    2. 공공데이터 API 불러오기
    3. Google Speech를 이용한 음성인식 및 음성안내
  2. 프로젝트 사용 순서
  3. 인터페이스 구현

결론 | 요약


서론

[문제정의]

여러분 모두 버스 정류장에서 버스가 도착한다는 알림을 음성으로 들은 경험이 한번쯤은 있으시겠죠. 하지만 최근 포항시에서는 시민들의 민원으로 인해 도착 정보의 음성 안내를 축소하거나 중단 되었다는 것을 아시나요? 포항 뿐만 아니라 다른 몇몇 지역에서도 버스 도착 정보를 화면에는 띄우지만, 음성으로 안내하는 서비스는 일부 중단되었다고 합니다. 그렇다면 시민들은 어떤 이유로 민원을 넣었기에 음성 안내 서비스가 축소 혹은 중단되었던 걸까요?

1

시민들이 민원을 넣었던 이유는 바로 소음 문제 때문이었습니다. 비장애인 시민들이 시끄럽다는 이유로 음성 안내 서비스를 중단하거나, 볼륨을 줄여달라는 민원을 넣은 것이었습니다. 하지만 시각장애인 및 저시력자들은 화면을 볼 수 없거나 보기 힘들기 때문에 음성 안내 서비스에 의존하는 것이 전부였는데요. 이러한 상황 때문에 시각장애인들은 버스를 이용하는데 큰 어려움을 겪게 되는 문제가 발생했습니다.

2

위 그림의 그래프를 보면 현재 상당 수의 시각장애인이 대중교통을 이용하는 것을 알 수 있습니다. 지하철, 전철과 버스를 이용하는 비율을 살펴보면 약 30%에 해당해 가장 큰 비율을 차지하는 장애인 콜밴과 거의 비슷한 비중을 차지하는데요.
하지만 여기서 주목해야 할 점은 버스 사용률는 많지 않다는 것을 알 수 있습니다. 그렇다면 시각장애인들은 어떤 이유로 버스를 잘 이용하지 않게 되었을까요?

아래의 표를 살펴보면, 교통 안내 정보가 부족하다는 의견이 거주지에서 택시, 전철, 버스정류장까지 이동하기 힘들다라는 의견과 함께 가장 큰 이유로 드러났습니다.

3


[우리의 목표]


4

스마트폰이 대중화되면서 시각장애인들도 스마트폰을 사용하는 비율이 높아지게 되었습니다. 이로써 시각장애인들이 스마트폰을 통해 많은 정보를 얻을 수 있게 되었다고 볼 수 있죠. 하지만 앞서 말씀드린 것과 같이, 여전히 대중교통을 이용하는 데에 있어서는 정보 파악에 부족함을 느낀다고 대답하였습니다.

그래서 저희는 !! 앞서 언급되었던 정보 부족이라는 문제점을 극복하기 위해 스마트폰을 이용하여 음성으로 안내 받는 버스 도착 안내 어플리케이션을 만들게 되었습니다.

6 7



물론, 현재 마켓에는 버스 도착 정보를 얻을 수 있는 많은 어플리케이션이 나와 있습니다. 그럼에도 불구하고 어플 캡쳐본을 보면 알 수 있듯이 시각 장애인들이 사용하기에는 작은 버튼과 글씨, 복잡한 인터페이스, 음성인식으로 검색 및 안내 불가 등 여러 조작의 어려움으로 인해 시각장애인들은 여전히 충분한 정보를 제공 받지 못하는 상황입니다.

따라서, 저희의 어플리케이션은 음성 인식을 기반으로 필요한 정보를 입력, 출력 할 수 있는 기능을 제공합니다. 또한 GPS기능을 사용하여 현재 위치한 버스정류장이 자동으로 인식되게 하고, 해당 정류장에서 사용자가 입력한 버스의 도착 정보를 제공하는 것을 목적으로 합니다. 단, 버스 도착 정보는 포항시 버스에 대해 제한적으로 제공되며, 사용자가 버스 정류장에 위치해있는 상황임을 가정하여 프로그램을 구성하였습니다.


[사용자 예상 조건]

여러 상황과 더불어 많은 변수가 존재하기 때문에, 저희는 프로젝트를 시작하기에 앞서 사용자 예상 조건을 먼저 정해보았습니다.

  • 사용자는 스마트 폰을 소지하고 있으며, 어플리케이션을 다운 받을 수 있다.
  • 사용자는 원하는 버스 정류장까지 갈 수 있다.
  • 사용자는 탑승할 버스 번호를 알고 있다.

본론

[ 1.적용한 기술 ]

저희는 안드로이드 어플리케이션을 만들기 위해 안드로이드 스튜디오 툴을 사용하였습니다.

Ⅰ. GPS로 현재 위치 인식

GPS를 이용하여 나의 위치를 확인하기 위해서는 4단계가 필요합니다.
1단계 : 위치 관리자 객체 참조하기
2단계 : 위치 리스너 구현하기
3단계 : 위치 정보 업데이트 요청하기
4단계 : 매니페스트에 권한 추가하기

그럼 이제 각 단계를 세부적으로 살펴보겠습니다 !

1단계 - 위치 관리자 객체 참조하기

위치 관리자(LocationManager)는 시스템 서비스이므로 객체를 참조하기 위해서는 getSystemService()메소드를 사용합니다. 우선 startLocationService() 메소드를 호출하고 이 메소드 안에는 내 위치를 확인하기 위한 코드를 입력합니다.

28

빨간 박스는 위치 관리자 객체 참조, 파란 박스는 최근에 확인했던 위치 정보 확인을 의미합니다.
위치 관리자를 위한 서비스 이름은 Context.LOCATION_SERVICE이므로 이 이름을 이용해 객체를 참조한 후, 최근 위치 정보를 확인해 보는 코드를 넣으면 바로 위치 정보를 확인할 수 있습니다. Location 객체는 위도와 경도값을 가지고 있으며, getLatitude()와 getLongitude()메소드를 이용해 그 값을 확인할 수 있습니다.

2단계 - 위치 리스너 구현하기

위치 리스너는 위치 관리자에서 전달하는 위치 정보를 받기 위해 정의된 인터페이스입니다. 즉, 위치 관리자가 위치 정보를 전달할 때 호출되므로 위치 정보를 받아 처리하기 위해서는 이 리스너의 onLocationChanged() 메소드를 구현해야 합니다.

29

3단계 - 위치 정보 업데이트 요청하기

위치 관리자는 일정한 시간 간격으로 위치 정보를 확인하거나 일정 거리 이상을 이동했을 때 위치 정보를 전달하는 기능을 제공합니다. 위치 관리자에게 현재 위치를 알려달라고 요청하기 위해서는 requestLocationUpdate() 메소드를 호출해야 하는데 파라미터로는 최소 시간과 최소 거리 그리고 위치 리스너 객체가 전달되어야 합니다.

30

빨간 박스는 새로 정의한 GPSListener 객체 생성, 파란 박스는 위치 관리자 객체의 requestLocationUpdates() 메소드를 호출하여 위치 정보 수신 시작을 의미합니다. 최소 시간으로는 10초, 최소 거리는 0으로 하여 10초마다 위치 정보를 전달받게 됩니다.

4단계 - 매니페스트에 권한 추가하기

GPS를 이용해 위치 정보를 받기 위한 권한은 ACCESS_FINE_LOCATION으로 정의되어 있으므로 다음과 같은 매니페스트에 권한을 추가해야 앱이 정상적으로 실행됩니다.
<uses-permission android:name=”android.permission.ACCESS_FINE_LOCATION" />
이 권한은 위험 권한으로 분류되어 있으므로 build.gradle(Moodule:app)파일을 열고 targetSDKVersion의 값을 22로 낮추는 것도 잊지 말아야 합니다 !

Ⅱ. 공공데이터 API불러오기

저희는 GPS를 통해 현재 위치의 위도, 경도 값을 받아와 공공데이터 API를 파싱하여 현재 있는 위치에서 가장 가까운 정류장의 데이터와 해당 정류장의 버스 도착 정보의 데이터를 가져왔습니다. 여기서 파싱(Parsing)이란, 어떤 페이지(문서, html 등)에서 자신이 원하는 데이터를 특정 패턴이나 순서로 추출하여 정보로 가공하는 것을 말합니다.

예상 사용자의 조건에 따르면, 사용자는 현재 버스 정류장에 위치해 있는 상황입니다. 사용자가 버스 어플을 실행하면 현재 위치해 있는 정류장의 이름을 음성으로 안내받습니다. 이는 GPS를 이용해 현재 위치의 좌표를 받아와 공공데이터 API를 통해 현재 위치한 버스 정류장의 이름, 위도, 경도를 읽어 옵니다. 그리고 화면 상에서는 제일 상위의 text 창에 띄워지게 됩니다! 다음은 공공데이터 API를 받아오기 위해 사용한 코드입니다.

XMLPullParser를 이용해 버스 정류장의 위치 정보를 받아오도록 하였습니다. 그리고 XML 파싱이 오래 걸릴 수 있으므로 쓰레드를 사용했습니다.

<XMLParser.java>
8

XMLParser는 URL을 이용해서 XMLPullParser 객체를 반환합니다. 이 반환된 것을 가지고 Tag 및 데이터를 가지고 오게 되는 것입니다. getXMLParser(string type)에서 type은 utf-8, euc-kr등 XML을 가지고 올 때 어떤 형태로 가지고 올 것인가를 설명해 주는 것입니다. 대부분 utf-8로 되어있지만 간혹 깨지는 경우에는 euc-kr로 변경해 보는 것을 추천합니다!

<BusStationXMLParser.java>
9 10 11

BusStationXMLParser는 XMLParser에서 가지고 온 버스 정류장의 정보를 이용해서 원하는 값을 BusStationDatas 객체에 저장해서 리스트를 만듭니다. 생성자로 handler를 받는 이유는! 쓰레드를 사용했기 때문에 파싱이 끝난 후 Activity 에 끝났다는 것을 전달하기 위함입니다. 또한 부모 class인 getXMLParser(“utf-8”)을 이용해서 XMLPullParser 객체를 받아오고 있습니다.

32번 째 줄은 getEventType()를 사용해서 현재 사건인지를 조사하며, 여기서 얻은 정보는 START_DOCUMENT(문서 처음), END_DOCUMENT(문서 끝), START_TAG(태그의 시작(), END_TAG(), TEXT(데이터)중 하나가 될 것입니다. 33번째 줄의 tagIdentifier는 각 태그를 식별하고 해당 태그의 데이터를 가져오기 위한 변수입니다. 그리고 next 에서드를 사용해서 다음 사건을 조사하면서 문서를 처음부터 순회합니다. getName 메서드는 태그를 가져오고, getText는 데이터를 가져오는 역할을 합니다. parsing이 끝나면 handler에게 empty message를 보내 줍니다.

실제 받아오는 버스 정류장 정보에 대해서는 다음과 같습니다.

12



여기서 원하는 정보는 gpslati, gpslong, nodenm인데요! 파싱할 때도 다른 정보는 빼고, 저 태그의 데이터만 가지고 오면 됩니다. 그 결과는 다음과 같습니다.

13



우선 이 결과는 현재 위치의 위도, 경도를 포항 육거리 정류장의 위도, 경도값을 가져와 임의로 만든 Url로 나온 결과이며 안드로이드 스튜디오 log창에 띄운 것입니다. 이처럼 공공데이터API는 tag의 데이터만 가져와 원하는 정보만을 얻을 수 있습니다.

Ⅲ. Google Speech를 이용한 음성인식 및 음성안내

저희는 구글 안드로이드에서 제공하는 google speech API를 통해 버스 도착 안내에 필요한 정보를 시각장애인에게 음성으로 입력 받고, 음성으로 출력할 수 있도록 만들어보았습니다. 안드로이드 자체에서 제공하는 google speech API를 이용함으로써 사용자에게 기능을 제공하였고, 사용자는 안드로이드 기기의 설정-일반-접근성 탭에서 기능 활성화를 조정할 수 있는데요. 이를 두가지로 나누어 설명하면 크게 STT(Speech To Text), TTS(Text To Speech)로 나눌 수 있습니다.

-STT

우선 STT(Speech To Text)는 사용자의 음성 입력을 스마트폰 화면상에 글자로 변환시켜주는 기능을 말합니다. 사용자가 알고자 하는 버스의 번호를 음성으로 입력 받아 화면상에 나타낼 수 있도록 STT를 사용하게 되었습니다.

STT 기능이 구현되는 원리를 간략하게 설명하자면, 음성으로 입력한 input이 서버로 stream 되고, 이제 서버에서는 voice가 text로 변환되어 이를 app으로 되돌려 보내는 방식입니다.

저는 STT와 TTS 기능을 사용하기 위해 이런 몇가지 instance를 만들었는데요, 각각의 쓰임을 간단히 주석으로 달아놓았습니다. 자세한 쓰임은 잠시 후 등장하니 그 때 설명하도록 하겠습니다.


19

정류장 인식 후에, 마이크 모양 버튼을 누르면 “버스 번호를 한 자리씩 숫자로 말씀하세요.”라는 말이 적힌 창이 뜨고 동시에 이 말을 음성으로 읽어줍니다. 그러면 이제 버스 번호를 한자리씩 숫자로 읽어주면 됩니다.


20

btnSpeak이라는 이름의 이미지 버튼을 누르면 음성 입력을 받기 때문에 setOnClickListener로 음성 입력을 시작하도록 설정해 두었습니다.

(화면에 나타나는 창은 이런 모습입니다.)
21


사용자에게 버스 번호 입력을 안내하는 음성이 나오고 나면, ‘딩동’ 하는 소리와 함께 음성 녹음이 시작됩니다. 아래에 보이는 promptSpeechInput() 에 해당하는 부분이지요. 사용자가 더 이상 말을 하지 않으면 자동으로 종료를 인식하고 또 다시 ‘딩동’소리와 함께 녹음은 종료됩니다. 찾아본 결과 약 2.75초 정도가 지나면 종료되어 있는 것으로 설정 되어있습니다.

22


여기서 입력 받은 버스 번호는 onActivityResult라는 object에서 stirng 변수 busnum에 저장되게 했습니다. 버스 도착 정보를 얻으려면 버스 정보를 넘겨야 하니까요..!

27



-TTS

다음으로 TTS(TextToSpeech)는 화면상에 나타난 글자를 음성으로 읽어주는 기능입니다. 사용자로부터 입력 받은 번호에 해당하는 버스의 도착 안내 정보를 공공 데이터에서 받아오면, 이를 화면에 나타내게 됩니다. 이것을 TTS기능을 사용해 음성으로 읽도록 하여 도착 정보를 들을 수 있게 했습니다.

24


그림 상단에 표시한 것 처럼 TTS 기능을 사용하기 위해서는 우선 main Activity class에서 TextToSpeech.OnInitListener 로부터 Implement를 해야 합니다. 그리고 TTS를 사용 할 때 쓸 언어도 설정할 수 있는데요, onInit() method에서 설정할 수 있습니다.

25


먼저 아래부분에 있는 onInit method부터 설명하자면, 간단히 말해 TTS 기능의 설정 부분이라고 생각하시면 됩니다. Result 값에 대해 한국어로 설정하기 위해 KOREA라고 적힌 것이 보이시죠? 그리고 언어 설정 뿐 아니라 음성 출력시에 나오는 목소리의 높낮이와 빠르기도 조절할 수 있습니다.

한편, TTS 결과는 speakOut(); 이라는 method를 통해 음성 출력이 되는데요. 만약 읽을 data가 없거나 언어가 지원되지 않는 경우에는 TTS 기능이 불가능 하다는 메시지를 띄우고, 해당 사항 없이 정상 작동 하는 경우에만 speakOut(); method를 실행합니다.

TTS를 사용하실 때 주의하실 점은, shutdown을 꼭 시키셔야 한다는 점입니다! OnDestroy method를 통해 리소스를 해제시키는 것이기 때문이죠.

이제 TTS를 사용할 준비가 되었습니다! 읽을 대상이 정해지고 나면, speakOut()이라는 object를 통해 음성 출력이 됩니다. 아래 코드는 STT를 통해 입력받은 txtSpeechInput의 결과를 text라는 string에 저장하고, 그것을 읽어주는 부분입니다. 프로그램에서 txtSpeechInput의 값만 바꿔가며 speakOut 메소드를 사용하도록 만들었습니다. 참고로, 여기서 QUEUE_FLUSH의 의미는 큐에 있는 내용을 비우고 새로운 내용, 즉 새로운 data를 읽어주겠다는 의미입니다. 이렇게 해야 그때 그때 바뀌는 data를 읽어낼 수 있겠죠?

26


[ 2.프로젝트 사용 순서 ]

14


프로그램 실행 시 **GPS로 사용자의 현재 위치를 파악**하고, 현재 사용자의 좌표를 기준으로 가장 가까운 버스 정류장을 찾아 화면에 나타냅니다.

15

해당 정류장이 인식된 후, 사용자는 하단의 버튼을 눌러 타고자 하는 버스의 번호를 음성으로 입력합니다.(예: 100-1번 버스의 경우 '일공공 다시 일' 혹은 '영공공 다시 일')

버스 도착 안내 정보는 STT(Speech to Text)기능을 통해 문자로 화면에 나타나고 TTS(Text to Speech)를 통해 사용자에게 확인 받을 수 있습니다. 이 때, 같은 번호의 버스 정보가 여러 개 존재할 경우 현재 위치 정류장에서 가장 가까운 버스의 정보를 받아옵니다.

16


화면에 해당 버스의 도착 정보가 나타나면, TTS기능을 이용해 사용자에게 음성으로 안내합니다.

만약 버스 정보가 존재하지 않거나 오류가 발생하는 경우에도 음성으로 안내합니다.

17


[ 3.인터페이스 구현 ]

  • 검은 화면과 큰 흰글씨

18

시각장애인 및 저시력자를 대상으로 하는 만큼, 가독성을 위해 가장 간단한 인터페이스를 구성하였습니다.

  • 단순한 조작 다양한 메뉴나 여러 레이어의 화면 대신, 한 화면에서 모든 것을 구축하여 음성 안내 에만 의존하여도 조작하기에 어려움이 없도록 구성하였습니다!! 또한 해당 정류장의 위치를 GPS를 통해 자동으로 인식하게 하여 사용에 더욱 편리함을 주고자 하였습니다.

결론

저희는 지금까지 시각장애인 및 저시력자를 위한 버스 도착 정보 안내 어플리케이션을 소개하였는데요. 간단하게 몇가지 특징을 요약해보겠습니다.

첫째, 단순한 인터페이스를 추구하여 간단한 메뉴 구성과, 검은 바탕에 흰 글씨를 사용하였습니다. 이를 통해 시각장애인이 어플리케이션을 통해 쉽게 정보를 얻을 수 있게 하였습니다.
둘째, 사용자의 GPS를 통해 현재 위치를 자동으로 인식하고, 버스 도착 정보 및 그에 필요한 정보들을 음성으로 입출력 하여 사용자가 편리하게 정보를 파악할 수 있도록 하였습니다. 시각장애인과 저시력자 뿐 아니라 비장애 사용자들도 편하게 사용할 수 있겠죠?



[앞으로의 계획] 첫 번째 파일은 GPS를 통해 현재 위치의 위도, 경도를 인식하여 가까운 정류소의 리스트를 log에 띄우는 것까지 구현되었고, 두 번째 파일은 현재 위치에서 가장 가까운 정류장의 위도, 경도 값을 임의로 설정하고 해당 정류장에서의 버스 도착 안내 데이터를 받아와 음성으로 입력 및 안내까지 구현되었습니다.

앞으로 더 개발해야할 부분은 가까운 정류소의 리스트 중에서 가장 가까운 정류소를 계산하여 그 데이터 값을 두 번째 파일로 보내 Url을 완성시키는 것입니다!!