"바른 생각 - 바른 자세"의 두 판 사이의 차이
EmSys2024A (토론 | 기여) (→동작 시나리오) |
EmSys2024A (토론 | 기여) (→프로젝트 평가) |
||
(같은 사용자의 중간 판 113개는 보이지 않습니다) | |||
15번째 줄: | 15번째 줄: | ||
==프로젝트 개요== | ==프로젝트 개요== | ||
− | ===프로젝트 요약=== | + | ===1. 프로젝트 요약=== |
본 프로젝트는 장시간의 집중시간을 편안한 자세로서 사용자에게 제공하는 것을 목표로 한다. 프로젝트는 모터를 통해 높이가 조절 되는 거치대를 기본으로 구성이 되어 있다. 이를 통해 사용자의 목과 팔꿈치의 부담을 줄이도록 해준다. 카메라를 통한 얼굴인식과 이를 이용한 알람 기능으로 사용자의 비집중 시간을 감지하여 알림을 제공한다. 프로젝트는 하드웨어를 제어하는 라즈베리파이 서버와 사용자의 입력을 기반으로 요청을 보내는 안드로이드 앱(클라이언트)으로 구성되어 있다. 서버와 클라이언트는 WiFi를 통해 1:1 TCP/IP통신을 한다. | 본 프로젝트는 장시간의 집중시간을 편안한 자세로서 사용자에게 제공하는 것을 목표로 한다. 프로젝트는 모터를 통해 높이가 조절 되는 거치대를 기본으로 구성이 되어 있다. 이를 통해 사용자의 목과 팔꿈치의 부담을 줄이도록 해준다. 카메라를 통한 얼굴인식과 이를 이용한 알람 기능으로 사용자의 비집중 시간을 감지하여 알림을 제공한다. 프로젝트는 하드웨어를 제어하는 라즈베리파이 서버와 사용자의 입력을 기반으로 요청을 보내는 안드로이드 앱(클라이언트)으로 구성되어 있다. 서버와 클라이언트는 WiFi를 통해 1:1 TCP/IP통신을 한다. | ||
사용자는 안드로이드 앱을 통해 높이 조절, 알람 시간 설정, 알람 모드 설정, 현재 촬영되는 영상 확인의 기능을 서버에게 요청할 수 있다. 또한 자신이 주로 사용하는 설정을 프로필을 만들어 저장하고, 불러올 수 있다. | 사용자는 안드로이드 앱을 통해 높이 조절, 알람 시간 설정, 알람 모드 설정, 현재 촬영되는 영상 확인의 기능을 서버에게 요청할 수 있다. 또한 자신이 주로 사용하는 설정을 프로필을 만들어 저장하고, 불러올 수 있다. | ||
서버는 클라이언트로부터 받은 요청을 바탕으로 하드웨어 제어를 하며 기능을 수행한다. 높이 조절 기능은 사용자가 요청한 높이로 모터를 제어하여 사용자가 요청한 높이로 거치대를 조절한다. 알람 기능을 사용자가 설정한 경우에는 카메라를 통해 사용자의 얼굴을 인식한다. 이 때 사용자의 얼굴이 인식되지 않으면, 사용자가 현재 집중을 하지 않고 있다고 판단하여, 시간을 측정한다. 측정한 시간이 알람 설정 시간이상이 되면 사용자가 요청한 알람 모드(소리, 진동)에 따라 알람을 제공한다. 사용자의 얼굴이 측정되지 않을 때는 LED 인디케이터를 통해 사용자에게 시작적인 알람을 제공한다. 이 때 사용자는 실제로 집중하고 있음에도 얼굴 인식이 되지 않고 있는 경우에는 자세를 바르게 하거나, 카메라 각도를 조절할 수 있게 된다. 서버는 사용자가 추가적인 요청을 보내면 현재 촬영 영상을 특정 웹주소를 통해 스트리밍한다. | 서버는 클라이언트로부터 받은 요청을 바탕으로 하드웨어 제어를 하며 기능을 수행한다. 높이 조절 기능은 사용자가 요청한 높이로 모터를 제어하여 사용자가 요청한 높이로 거치대를 조절한다. 알람 기능을 사용자가 설정한 경우에는 카메라를 통해 사용자의 얼굴을 인식한다. 이 때 사용자의 얼굴이 인식되지 않으면, 사용자가 현재 집중을 하지 않고 있다고 판단하여, 시간을 측정한다. 측정한 시간이 알람 설정 시간이상이 되면 사용자가 요청한 알람 모드(소리, 진동)에 따라 알람을 제공한다. 사용자의 얼굴이 측정되지 않을 때는 LED 인디케이터를 통해 사용자에게 시작적인 알람을 제공한다. 이 때 사용자는 실제로 집중하고 있음에도 얼굴 인식이 되지 않고 있는 경우에는 자세를 바르게 하거나, 카메라 각도를 조절할 수 있게 된다. 서버는 사용자가 추가적인 요청을 보내면 현재 촬영 영상을 특정 웹주소를 통해 스트리밍한다. | ||
− | ===프로젝트의 배경 및 기대효과=== | + | ===2. 프로젝트의 배경 및 기대효과=== |
====가. 배경==== | ====가. 배경==== | ||
30번째 줄: | 30번째 줄: | ||
: 책상에 앉아 장시간 업무를 진행 할 때 신체에 부담을 주는 자세를 개선하고 높은 집중 시간을 유지하는 데 도움이 되는 기구를 개발한다. 앱으로 사용자가 원하는 각도를 세밀하게 조정할 수 있고, 졸음 인식 기능과 알람 기능을 삽입하여 신체의 부담을 줄이고 효율성을 높인다. | : 책상에 앉아 장시간 업무를 진행 할 때 신체에 부담을 주는 자세를 개선하고 높은 집중 시간을 유지하는 데 도움이 되는 기구를 개발한다. 앱으로 사용자가 원하는 각도를 세밀하게 조정할 수 있고, 졸음 인식 기능과 알람 기능을 삽입하여 신체의 부담을 줄이고 효율성을 높인다. | ||
− | ===프로젝트 개발 목표=== | + | ===3. 프로젝트 개발 목표=== |
− | [[파일:목적 계통도.png]] | + | [[파일:목적 계통도.png|800픽셀|섬네일|가운데|목적 계통도]] |
====가. 기능성==== | ====가. 기능성==== | ||
:*강건성 | :*강건성 | ||
51번째 줄: | 51번째 줄: | ||
==동작 시나리오== | ==동작 시나리오== | ||
− | [[파일:사용자 시나리오.png| | + | [[파일:사용자 시나리오.png|1200픽셀|섬네일|가운데|사용자 시나리오]] |
+ | |||
+ | ==역할분담 및 개발 일정== | ||
+ | ===1. 역할분담 === | ||
+ | ====정*==== | ||
+ | <strong>[전체 진행 및 서버 시스템 개발 총괄, 통신 시스템 개발, 하드웨어 제어 시스템 개발, 회로도 설계]</strong> | ||
+ | |||
+ | 프로젝트 진행 상황을 총괄하여 부품 구매 및 관리, 역할 분담 및 일정 조율을 수행했다. 프로젝트의 진행 방향을 정하고 팀 인원들의 개발 계획 및 결과를 시스템의 요구 사항과 비교하여 불가여부를 판단했다. 서버와 클라이언트의 통신 패킷의 설계했다. 서버 시스템에서 비집중 감지 모듈을 제외한 시스템을 구현했다. 라즈베리 파이의 GPIO제어를 위한 회로도와 시스템을 설계 및 개발 했다. | ||
+ | |||
+ | ====김*현==== | ||
+ | <strong>[앱 시스템 개발 총괄, 앱UI, 하드웨어 개발]</strong> | ||
+ | |||
+ | 앱 시스템 개발팀을 총괄하여 진행 사항 공유 및 역할 분담을 수행했다. 앱의 UI 시나리오를 설계 하고 구현했다. 앱의 프로필 시스템을 설계하고 구현했다. 높이 조절 기능을 하는 구동부의 부품 설계를 진행했다. | ||
+ | |||
+ | ====김*준==== | ||
+ | <strong>[하드웨어 개발 총괄, 비집중 감지 모듈 개발, 영상 스트리밍 모듈 구현]</strong> | ||
+ | |||
+ | 높이 조절 기능을 하는 구동부를 전체적으로 설계했다. 구동부의 부품을 설계하고 3D프린터를 통해 구현하는 과정을 총괄 했다. 카메라를 통해 사용자의 얼굴을 인식하고, 이를 통해 비집중 시간을 감지하는 모듈을 개발했다. 카메라의 영상을 특정 웹주소를 통해 Mjpeg over HTTP 방식으로 스트리밍 하는 모듈을 구현했다. | ||
+ | |||
+ | ====권*표==== | ||
+ | <strong>[사전 연결 개발 총괄 앱UI, 앱 WiFi 연결 개발, 스트리밍]</strong> | ||
+ | |||
+ | 사전 연결 개발 부분을 구현했다. 앱 내부 WiFi 연결 및 서버 핫스팟 연결 과정을 진행했다. 같은 와이파이 내부에서 서버의 ip탐색을 설계했다. 웹 주소를 통한 앱 내부 스트리밍 기능을 구현하고 앱 구동 기능 및 UI를 개발했다. | ||
+ | |||
+ | ===2. 개발 일정=== | ||
+ | |||
+ | [[파일:바른생각개발일정.png|1200픽셀|섬네일|왼쪽|개발 일정표]] | ||
+ | <br><br><br><br><br><br><br><br><br><br><br> | ||
+ | <br><br><br><br><br><br><br><br><br><br><br> | ||
+ | <br><br><br><br><br><br><br><br><br><br><br> | ||
==구현 내용== | ==구현 내용== | ||
===시스템 구성=== | ===시스템 구성=== | ||
+ | [[파일:시스템 구성도.png|800픽셀|섬네일|가운데|시스템 구성도]] | ||
+ | |||
+ | :본 시스템의 설계 구성도는 위와 같다. 클라이언트와 서버는 WiFi환경을 기반으로 TCP/IP 통신을 진행한다. 클라이언트의 요청을 서버는 연결된 기기를 제어하여 처리한다. 카메라를 통해 사용자 얼굴을 인식하여 비집중 감지, 영상 스트리밍 등의 기능을 수행한다. 사용자의 요청을 처리함에 따라 필요한 하드웨어 출력 장치를 선택하여 제어한다. | ||
===기구부 설계 및 구현=== | ===기구부 설계 및 구현=== | ||
+ | :하드웨어의 최종 제품은 그림 4과 같이 설계하였고 전체적으로 상판, 선반 그리고 하판으로 이루어져 있다. 상판은 사용자가 물건을 올려놓고 사용하는 공간으로 노트북이나 태블릿과 같은 여러 물건을 올려놓고 작업할 수 있도록 충분한 크기인 800×550(mm) 크기로 제작했다. 두께는 12mm로 얇은 목재를 사용하여 상판자체의 무게를 줄였다. 또한 사용자의 팔꿈치가 몸의 중심보다 뒤로 가게 하여 어깨의 부담감을 줄일 수 있도록 중앙에 홈을 파여 디자인했다. | ||
+ | :선반의 경우, 너비 길이는 상판과 경첩으로 부착되므로 상판과 같은 너비로 설계했다. 모터는 상판 연결부를 들어올리는 방식을 취하고 있으므로 책상면과 선반은 평행을 이루도록 설계하였다. 모터의 선반 받침대과 결합된 선반은 회전을 하지 않고 위아래로만 움직이며, 따라서 상판의 각도를 조절하는 역할을 수행하게 된다. | ||
+ | :하판 위에는 장치들과 전선들을 배치하였고, 상단에 케이스를 가려 전체적으로 깔끔한 외관을 보여 완성도 있도록 설계하였다. 이때 하판의 높이를 최소화하기 위해서 가장 얇은 두께인 12mm 목재로 구매했다. | ||
+ | |||
+ | ====가. 각도 설계==== | ||
+ | [[파일:최대최저각도.JPG|800픽셀|섬네일|가운데|최대, 최저각도]] | ||
+ | :프로젝트의 하드웨어 구성 요소 중 핵심 기능인 각도 조절 설계는 그림 A와 같이 진행하였다. 상판은 선반과 경첩을 이용해 고정되어 있으며, 이 구조를 통해 선반의 상승과 하강에 따라 상판과 바닥면 사이의 각도가 동적으로 변화하는 메커니즘을 구현하였다. | ||
+ | :선반의 높이는 최저 각도에서 77mm로 설정되었고, 이때의 상판 기울기는 8.04°으로 측정되었다. 선반의 상승으로 인한 최대 높이는 172mm로 제한하였으며, 이 경우에는 상판의 기울기가 18.28°로 증가한다. 또한, 세밀한 각도 조절을 위해 높이 조절 단계는 총 20단계로 구성되어 있으며, 이는 각 단계마다 약 0.5°의 기울기 변화를 의미한다. 이와 같은 각도 조절 설계를 통해 사용자의 요구에 따라 동적인 선반 높이와 상판의 각도를 조절할 수 있다. | ||
+ | |||
+ | ====나. 높이 조절 구동부==== | ||
+ | [[파일:높이 조절 메커니즘.JPG|800픽셀|섬네일|가운데|높이조절메커니즘]] | ||
+ | :선반의 수직 이동 기능은 스텝 모터와 모터 나사선에 고정된 선반 받침대를 통해 수행된다. 이 세 구성요소는 상호작용하여 선반의 상승과 하강을 구현한다. 선반 받침대의 상단면은 선반의 하단면과 밀착해 고정되어 있으며, 스텝 모터의 나사선은 하판에 수직으로 고정되어 있다. 이 스텝 모터의 나사선은 시계방향(CW)과 반시계방향(CCW)으로 양방향 회전이 가능하다. 따라서 스텝 모터의 시계 방향 회전 동작은 선반 받침대의 상승을 초래한다(그림 (a) 참조). 이는 모터의 회전 방향이 선반 받침대의 수직 움직임에 직접적으로 영향을 미치는 것을 보여준다. 반대로, 스텝 모터가 반시계 방향으로 회전할 때에는 선반 받침대가 하강한다(그림 (b) 참조). 따라서, 이러한 스텝 모터의 정교한 제어와 연동 구조는 선반의 수직 이동 기능의 핵심 요소로 작용한다. | ||
+ | |||
+ | ====다. 구동부 안정화 고정대==== | ||
+ | [[파일:회전 고정대 기능.JPG|800픽셀|섬네일|가운데|회전 고정대 기능]] | ||
+ | :모터의 시계방향 및 반시계방향 구동 시 발생할 수 있는 상판의 진동을 제어하고, 선반의 회전 토크에 대응하기 위해 선반 양쪽 끝부분에 회전 방지 장치를 설치하였다, 위 그림은 모터의 양방향 회전에 대응하여 회전 고정대가 토크 방향을 안정화하는 과정을 시각적으로 나타내고 있다 | ||
===제어부 및 회로 구현=== | ===제어부 및 회로 구현=== | ||
+ | [[파일:회로도 설계.PNG|800픽셀|섬네일|가운데|회로도 설계]] | ||
+ | |||
+ | :본 프로젝트에서는 스피커, 진동 모터, LED, 모터 드라이버를 통한 모터, 카메라 등 다양한 디바이스를 사용한다. 실제 구동을 통해 알아낸 핀의 개수와 종류를 맞추어서 설계하였다. 프로젝트의 전체적인 완성도를 위해, 이들 디바이스를 하나의 통합된 시스템으로 구성하는 것에 중점을 두었다. 이를 위해 전체 시스템을 위한 회로도를 디자인하였다. 모터, 모터드라이버 와 나머지(LED,스피커,부저)를 구분지어 회로를 구성했다. 모터와 모터드라이버는 GPIO제어에 비해 더 많은 전력을 사용하기에 별도로 구성했다. pwm 신호를 사용하는 스피커, 진동모터는 하나의 pwm 출력을 회로를 통해 같이 받을 수 있도록 하였다. 전원 핀을 통해 둘 중 pwm신호를 받을 기기를 선택할 수 있도록 했다. | ||
+ | |||
+ | [[파일:실제 회로도.jpg|800픽셀|섬네일|가운데|실제 회로도]] | ||
+ | |||
+ | :실제로 구현한 제어부 및 회로는 다음과 같다. 상판에 부착되는 LED와 부저는 연장 케이블로 연결될 수 있도록 하였다. | ||
+ | |||
+ | ===통신부 설계 및 구현=== | ||
+ | [[파일:통신 패킷 구성도2.png|800픽셀|섬네일|가운데|통신 패킷 구성도]] | ||
+ | :패킷의 설계에 앞서 HTTP 구조를 통해 패킷의 구성 요소 및 스펙을 참고했다. 경량 패킷으로서 파싱 및 내용 추가가 용이한 구조로 설계 했다. 통신의 안정성 검사를 위한 최소한의 헤더와 JSON형식을 이용한 패킷 바디로 이루어여있다. JSON의 key값은 숫자 인덱스를 사용하여 바디의 크기를 최적화했다. 위와 같은 패킷의 설계로, 서버와 클라이언트 TCP 통신을 안정적이게 진행 할 수 있었고, 통신 중에 평균 30~40byte의 패킷을 주고 받게 되었다. 각 패킷의 내용은 기본적으로 의미없는 기본값이 존재하며 서버는 이를 통해 불필요한 처리를 줄일 수 있다. 경량화를 위해 알람모드는 비트 마스크를 사용하였다. | ||
+ | |||
+ | [[파일:패킷 파싱 흐름도2.png|800픽셀|섬네일|가운데|패킷 파싱 흐름도]] | ||
+ | :헤더의 정보를 통해 패킷의 Body 길이를 알수 있다. 이를 이용해 body가 처음부터 끝까지 올바르게 왔는지 검사한다. 이 후 Body가 JSON형식인 것을 이용해 손쉽게 파싱한다. | ||
+ | |||
+ | ==소프트웨어 설계 및 구현== | ||
+ | |||
+ | ===1. 라즈베리 파이 서버 === | ||
+ | |||
+ | 서버 시스템은 WiFi 연결과 Listening Socket 생성을 하는 '서버 Listen' 단계와 클라이언트의 요청을 처리하는 '요청 처리' 두 부분으로 나뉜다. | ||
+ | |||
+ | [[파일:라즈베리파이 서버2.png|1200픽셀|섬네일|가운데|서버 시스템 흐름도]] | ||
+ | |||
+ | ==== 1.1 서버 Listen ==== | ||
+ | Ubuntu NetworkManager 패키지를 이용하여 사전에 정의된 WiFi에 연결합니다. 이후 TCP 서버 소켓을 만들고 클라이언트의 접속을 기다린다. | ||
+ | |||
+ | ==== 1.2 요청 처리 ==== | ||
+ | 클라이언트의 요청이 담긴 패킷을 받고, 이를 파싱하여 그에 따른 동작을 수행하는 과정이다. 서버는 클라이언트에게 다음과 같은 4가지 기능을 제공한다: | ||
+ | |||
+ | * 모터 제어 | ||
+ | :: 모터 제어 프로세스는 사용자의 목표 단계가 담긴 queue를 받아, 이를 비울 때까지 모터를 제어하여 처리하는 동작을 한다. 서버는 사용자의 요청을 즉시 실행할 수 없을 때는 queue에 담고, 실행 가능할 때 q를 복사하여 위의 모터 제어 동작을 하는 프로세스를 생성한다. 그러나 서버의 패킷 파싱 이후 모터 제어 프로세스 생성 유무를 결정하기 때문에, 기존의 모터 제어 프로세스가 종료 후, 새로운 요청이 도착해야만 q에 담긴 요청이 실행되는 문제가 있다. | ||
+ | [[파일:모터 제어 프로세스.png|700픽셀|섬네일|가운데|모터 제어 프로세스 흐름도]] | ||
+ | * 비집중 시간 감지 및 알람 | ||
+ | :: 서버는 사용자가 알람 관련 기능을 설정하면, 비집중 감지 프로세스를 생성한다. 감지 프로세스는 사용자가 얼굴이 인식되지 않는 상황을 비집중 시간이라고 판단한다. 비집중이 인식되면 LED를 통해 경고한다. 측정 결과에 따라 ’집중‘, ’비집중‘ 두가지 상태로 구분한다. 바로 전 프레임의 상태를 저장하고, 이를 현 프레임과 비교한다. 만약 상태가 달라지면 달라지는 시점을 저장한다. 이후 가장 최근에 기록한 시점으로부터 경과한 시간이 알람 시간보다 크고, 현재 상태가 ’비집중 상태‘라면 알람 모드에 따라 알람을 울린다. | ||
+ | [[파일:비집중 감지 프로세스.png|700픽셀|섬네일|가운데|비집중 감지 프로세스 흐름도]] | ||
+ | * 영상 스트리밍 | ||
+ | :: 사용자의 얼굴 인식 결과 영상을 특정 웹주소를 통해 Mjpeg over HTTP 방식으로 계속해서 스트리밍 한다. Flask 프레임 워크를 이용하여 구현했다. 해당 기능을 python을 통해 실행하는데, 이때 rasberry Pi 프로세스에게 큰 부하가 발생한다. 따라서 10분 이상 동작하면 프로세스의 쓰로틀링을 유발하고, 서버의 처리 속도가 매우 늦어지거나 혹은 라즈베리 파이가 종료 될 수 있는 문제점이 있다. | ||
+ | [[파일:영상 스트리밍 흐름도.png|700픽셀|섬네일|가운데|영상 스트리밍 흐름도]] | ||
+ | * 전원 제어 | ||
+ | ::자원 회수 이후 OS의 종료기능을 이용하여 라즈베리 파이를 종료시킨다. 처음으로 소켓을 모두 닫는다. 이후 모터 제어를 통해 기기 상태를 초기화 한다. 이후 초기화가 끝나면 프로세스를 차례로 종료 시킨 후, Process 객체를 반환한다. 이후 공유 메모리 공간을 반환한다. 자원회수가 끝난 후에는 os 명령어를 이용해 라즈베리 파이를 종료 시킨다. 따라서 라즈베리파이가 아닌 독립적으로 전력을 공급받는 모터와 모터 드라이버는 종료하지 못한다는 문제점이 있다. | ||
+ | [[파일:자원 제어 흐름도.png|700픽셀|섬네일|가운데|자원 제어 흐름도]] | ||
+ | |||
+ | ===2. 안드로이드 app 클라이언트=== | ||
+ | |||
+ | 클라이언트 시스템은 WiFi연결 및 Socket 통신 준비 단계와 프로필 저장값을 토대로 앱 실행 시 소켓을 전달하는 초기값 전달 단계, 입력에 따른 통신 단계로 나뉜다. | ||
+ | |||
+ | [[파일:App 개략도.PNG|1200픽셀|섬네일|가운데|클라이언트 시스템 흐름도]] | ||
− | === | + | ==== 2.1 앱 UI ==== |
+ | <div><ul class = "center"> | ||
+ | <li style="display: inline-block;">[[파일:홈 화면.png|400픽셀|섬네일|가운데|홈 화면]]</li> | ||
+ | <li style="display: inline-block;">[[파일:높이 조절 화면.png|400픽셀|섬네일|가운데|높이 조절 화면]]</li> | ||
+ | <li style="display: inline-block;">[[파일:알람 설정 화면.png|400픽셀|섬네일|가운데|알람 설정 화면]]</li> | ||
+ | </ul></div> | ||
+ | *’홈 화면‘의 경우 사용자가 설정한 프로필 인자들을 확인할 수 있고 프로필 추가, 프로필 변경, 전원끄기, 영상확인 버튼을 눌러 해당 기능들을 수행할 수 있다. 프로필 추가 및 변경, 영상 확인 버튼을 누르게 되면 해당 기능을 수행하는 화면으로 이동하고 전원 끄기 버튼을 누르면 서버로 종료 요청을 보낸다. | ||
+ | |||
+ | *’높이 조절 화면‘의 경우 사용자가 직접 입력하거나 상, 하 버튼을 이용하여 설정한 단계를 서버로 보내고 해당하는 단계를 사용자가 볼 수 있도록 구현하였다. 또한 단계 저장 버튼을 누르면 현재 단계값을 사용자의 최적 단계로 저장한다. | ||
+ | |||
+ | *’알람 설정 화면‘의 경우 알람을 키거나 끌 수 있고 키는 경우 알람시간과 알람모드를 설정할 수 있게 구현하였다. 설정 저장 버튼을 누르는 경우 해당 값들을 현재 선택된 프로필에 저장한다. | ||
+ | |||
+ | <div><ul class="center"> | ||
+ | <li style="display: inline-block;">[[파일:프로필 추가 화면.png|700픽셀|섬네일|가운데|프로필 추가 화면]]</li> | ||
+ | <li style="display: inline-block;">[[파일:프로필 목록 화면.png|700픽셀|섬네일|가운데|프로필 목록 화면]]</li> | ||
+ | <li style="display: inline-block;">[[파일:스트리밍 화면.png|700픽셀|섬네일|가운데|스트리밍 화면]]</li> | ||
+ | </ul></div> | ||
+ | |||
+ | *'프로필 추가 화면'은 사용자의 편의를 위해 프로필을 추가하는 화면으로 이름, 알람 관련 사용자 설정을 프로필에 추가하고 저장한다. | ||
+ | |||
+ | *'프로필 목록 화면'은 사용자가 기존에 저장한 프로필의 목록을 나타내며 이 중 사용하고 싶은 프로필은 선택 버튼을 누르면 되고 삭제하고 싶은 경우 삭제 버튼을 누르면 된다. | ||
+ | |||
+ | *'스트리밍 화면'은 사용자가 영상 확인 버튼을 누를 경우 나타나며 기기에 연결된 카메라에서 송출되는 영상이 출력된다. 영상이 로딩되는 동안 로딩 바가 나타나며 close 버튼을 누르면 영상이 종료되고 홈 화면으로 돌아간다. | ||
+ | |||
+ | ==== 2.2 WiFi 연결 ==== | ||
+ | |||
+ | 사전에 사용자로부터 입력받은 WiFi에 연결한 후, 소켓 통신을 통해 서버에 해당 와이파이의 SSID와 비밀번호를 패킷 형식으로 보낸 뒤 동일한 WiFi에 연결된 서버의 IP Address와 사전에 결정한 포트번호로부터 소켓 통신을 진행한다. | ||
+ | |||
+ | ==== 2.3 초기값 전달 ==== | ||
+ | |||
+ | 소켓 통신이 정상적으로 진행되는 경우 앱 실행 시 프로필 값을 토대로 서버에 패킷을 보낸다. 이는 설정해놓은 프로필 값에 따라 스트리밍 서버 동작 여부가 결정되기 때문이다. | ||
+ | |||
+ | ==== 2.4 프로필 설정 및 입력에 따른 통신 ==== | ||
+ | |||
+ | 프로필을 추가, 변경 및 삭제하거나 사용자가 입력에 해당하는 버튼을 누르는 경우 이를 패킷화 시키고 서버에 보내는 과정이다. 패킷을 보내는 주기가 너무 빨라지는 경우 socket을 bind하는 과정에 문제가 생길 수 있기 때문에 서버의 응답을 받기 전까지 대기화면을 출력한다. 또한 서버의 응답을 스트리밍 주소로 받는 경우, 스트리밍된 주소로 이동하여 사용자에게 영상을 제공한다. | ||
+ | |||
+ | *프로필 | ||
+ | |||
+ | ::앱을 실행했을 때 기존에 선택해놓은 프로필이 있는 경우, Kotlin에서 제공하는 SharedPreference 기능(앱 내부 데이터 사용)을 사용하여 해당 프로필의 알람 시간과 알람 모드에 해당하는 값을 패킷화시킨다. 이렇게 만들어진 패킷을 서버로 보내 스트리밍 서버 동작 여부를 결정한다. 프로필이 없는 경우에는 데이터를 저장하는 것에 대한 불편함이 생길 수 있기 때문에 프로필 추가 화면으로 이동하도록 설정하였다. | ||
+ | |||
+ | [[파일:프로필 흐름도.png|700픽셀|섬네일|가운데|프로필 흐름도]] | ||
+ | |||
+ | *전원 끄기, 카메라 화면 확인 | ||
+ | |||
+ | ::홈 화면에서 전원끄기 버튼을 누르는 경우 패킷의 전원 인자를 수정하여 서버에 보낸다. 서버는 전원인자가 수정되는 것을 확인하고 서버를 종료한다. 카메라 확인 버튼을 누르는 경우 스트리밍 화면으로 넘어가 패킷의 스트리밍 인자를 수정하고 서버에 보내면 서버로부터 스트리밍 주소를 받아 화면에 출력하게 된다. 이후 닫기 버튼을 누르게 되면 스트리밍 요청인자를 원래 기본값으로 수정하여 스트리밍 서버를 종료시킨다. | ||
+ | |||
+ | [[파일:전원 끄기 및 카메라 확인 흐름도.png|700픽셀|섬네일|가운데|전원 끄기 및 카메라 확인 흐름도]] | ||
+ | |||
+ | *높이 조절, 알람설정 | ||
+ | |||
+ | ::높이 조절과 알람 설정 기능의 경우 각각 높이 조절 화면, 알람 설정 화면에서 구현된다. 높이 조절의 경우 사용자가 입력값을 입력하거나 높낮이 버튼을 눌러 패킷의 높이 조절 인자를 수정하고 서버로 보내 모터의 높낮이를 조절한다. 조절된 높낮이는 화면에 표시되며 최적 단계 저장 버튼을 통해 이를 프로필 값에 저장할 수 있다. | ||
+ | |||
+ | ::알람 설정의 경우 알람 시간과 알람 모드를 입력값 및 버튼으로 설정한 뒤에 저장 버튼을 누르면 현재 선택된 프로필 인자를 입력한 값으로 수정하고 그에 따라 패킷을 수정하여 서버로 보낸다. | ||
+ | |||
+ | [[파일:높이 조절 및 알람 설정 흐름도.png|700픽셀|섬네일|가운데|높이 조절 및 알람 설정 흐름도]] | ||
==프로젝트 결과== | ==프로젝트 결과== | ||
69번째 줄: | 218번째 줄: | ||
===최종 결과물=== | ===최종 결과물=== | ||
− | 결과물 사진 | + | ====결과물 사진==== |
+ | [[파일:최종 결과물.jpg|700픽셀|섬네일|가운데|최종 결과물]] | ||
+ | |||
+ | ====영상 링크==== | ||
+ | |||
+ | 프로필 추가 및 각도 조정 :https://www.youtube.com/watch?v=9ePsnrU0e_o | ||
+ | |||
+ | 멀티 프로세싱 ( 각도 조정하면서 스트리밍 영상 확인 ) : https://www.youtube.com/watch?v=IZEqMqtJtLg | ||
+ | |||
+ | 전원 끄기 : https://www.youtube.com/watch?v=96WSgqh2PZo | ||
===미구현 내용=== | ===미구현 내용=== | ||
+ | |||
+ | ====사전 연결==== | ||
+ | [[파일:사전 연결 개략도.png|1000픽셀|섬네일|가운데|사전 연결 개략도]] | ||
+ | |||
+ | |||
+ | [[파일:와이파이 입력 화면.png|700픽셀|섬네일|가운데|와이파이 입력화면]] | ||
+ | |||
+ | 사전 연결 과정은 앱에서 WiFi 이름과 비밀번호를 입력받은 뒤 앱 내부 데이터에 저장 후 라즈베리 파이의 hotspot에 연결하고 WiFi 이름, 비밀번호 데이터를 라즈베리 파이에 보내고 각각 앱과 라즈베리 파이가 해당 데이터를 통해 같은 WiFI에 접속한 뒤 앱에서 라즈베리 파이의 ip를 탐색 후 소켓 연결을 하는 과정이었다. | ||
+ | |||
+ | |||
+ | WiFi 데이터를 라즈베리 파이 hotspot에 접속한 후 패킷을 통해 데이터를 전송하고 서로 같은 WiFi 연결에 연결하는 것은 성공하였으나 이후 라즈베리 파이의 ip 주소를 찾는 부분에서 문제가 발생하였다. 라즈베리 파이 주소를 찾기 위해서 같은 WiFi 주소 내에서 ip suffix 부분을 바꿔가면서 ping 명령어를 보내고 응답 메시지를 받는 방법을 시도하였다. 하지만 WiFi 내에 다른 기기가 네트워크에 연결되어있는 경우 다른 기기 또한 응답을 보낼 수 있어 라즈베리 파이의 IP 주소를 특정할 수 없었으며 통신하는 데 어려움이 발생하였다. 또한 특정 공유기에서는 네트워크 방화벽 구성에 의해 ICMP ping 요청이 차단되어 정확한 IP 주소를 확인할 수 없는 경우가 발생하였다. 따라서 ip 주소를 일일이 찾아가는 방법을 구현하지 않고 고정 ip를 사용하는 방법으로 바꾸었다. | ||
==프로젝트 평가== | ==프로젝트 평가== | ||
− | ===평가항목=== | + | ===평가항목 및 결과=== |
+ | <br> | ||
+ | [[파일:바른생각평가결과.png|800픽셀|섬네일|가운데|평가항목 및 결과]] | ||
+ | |||
+ | ====설문조사 내용==== | ||
+ | <br> | ||
+ | |||
+ | [[파일:설문지.png|400픽셀|섬네일|가운데|설문지]] | ||
− | === | + | 위의 설문지를 바탕으로 시연을 해본 사용자들에게 설문을 진행하였다. |
+ | |||
+ | <br> | ||
+ | |||
+ | [[파일:설문조사내용.PNG|800픽셀|섬네일|가운데|설문조사결과]] | ||
+ | |||
+ | ====결과 분석==== | ||
+ | |||
+ | |||
+ | 사용성 측면에서는 긍정적인 답변을 받았다. 그러나 차후 사용 의향에서 낮은 점수를 받았는데, 모터의 소음이 가장 큰 원인으로 생각된다. 또한 기타 의견으로는 하드웨어 구조적 문제가 눈에 띄었다. 현재 상판은 모터의 축에만 고정되어 있다. 따라서 실사용에 불편함이 존재하기 때문이라고 생각된다. | ||
==느낀점== | ==느낀점== | ||
+ | 정* | ||
+ | :팀장을 맡게 되었을 때 현대 프로그래밍 기법에 대한 책을 읽었었고, 이를 실제로 활용하고 싶었다. 우선적인 시스템 설계와 흐름도를 통한 가구현. 그것을 바탕으로한 개발 업무 분리 및 테스트 케이스 설정. 팀 별 코딩 규칙 등 효율적인 팀 개발을 위해 새로운 작업 방식과 기법을 도입했다. 우선 처음 접해본 개념에 혼란스러웠을텐데도 잘 따라와준 팀원들에게 감사의 말을 전하고 싶다. 시스템의 요구사항과 스펙을 정하고 사전에 문제점을 미리 파악해가며 설계를 진행했기 때문에, 시간 대비 더욱 효율적인 개발이 가능했던 것 같다. 이렇게 완성된 프로그램은 구현에서 선택한 요인들이 모두 합리적인 이유를 가지고 있었으며, 결과적으로 개발 시간 대비 효율적인 구조를 가지면서 높은 안정성, 확장성을 가진 서버를 개발할 수 있었다. 현대 프로그래밍 기법이 왜 중요한지, 그에 대한 효능을 몸소 체험할 수 있었다. 더욱 더 많이 연습하며 능숙해져야겠다고 생각할 수 있었다. 하드웨어 부분에서 경험자가 없다보니 많은 난관이 있었다.그럴 때마다 다같이 토의를 하며 해결할 수 있었지만 기구학을 고려한 설계는 경험이 매우 중요하다는 것을 배울 수 있었다. | ||
+ | |||
+ | 김*현 | ||
+ | :학부에서 배운 내용을 실제로 적용해볼 기회가 드물고 이에 대한 아쉬움이 항상 있었는데 임베디드시스템이라는 과목에서 그 아쉬움이 적지 않게 해소되었던 것 같다. 물론 하드웨어를 설계하고 구현하는 과정과 앱 개발 과정에서 시행착오도 많이 겪고 어려움을 많이 느끼기도 하였다. 특히 처음 시도해보는 앱 개발의 경우 한 학기 안에 코틀린에 대한 기초적인 문법 공부부터 실제 환경에서 버그 없이 잘 작동하는 앱을 만들기까지의 과정이 쉽지는 않았지만 핸드폰에 설치해서 기능 하나하나가 잘 구현되는 것을 보는 재미가 더 컸기 때문에 끝까지 앱 개발을 진행할 수 있었고 성공적으로 잘 마무리할 수 있었던 것 같다. 또한 중간에 원래 계획했던 내용이나 개발 중이였던 기능을 시간 상 제외시켰던 경우도 있었으나 결과적으로 이러한 과정이 있었기 때문에 완성도 높은 제품을 만들 수 있다는 것을 직접 체감해볼 수 있었다. 마지막으로 이 과정을 큰 마찰 없이 마무리한 배울 점 많은 팀원들, 막막할 때마다 도움을 주신 교수님과 조교님들께 감사하다는 말을 전하고 싶다. | ||
+ | |||
+ | 권*표 | ||
+ | :과의 특성에 맞게 기계와 소프트웨어를 융합하는 방법을 처음으로 겪어보는 시간이었다. 이번 임베디드 시스템 프로젝트에서 가장 큰 도전은 하드웨어와 소프트웨어를 효율적으로 통합하는 것이었다. 이러한 설계를 진행하면서 하드웨어의 성능, 제약 사항, 인터페이스 등을 이해하고 소프트웨어와 원활하게 통신하는 방법을 찾아야 했다. 프로젝트를 진행하면서 하드웨어와 소프트웨어를 밑에서 부터 설계하는 것이 굉장히 어려운 것이라는 것을 느꼈다. 또한 이러한 통합 작업은 시간과 노력이 많이 필요하지만, 정확한 통합을 통해 최종 제품의 성능을 극대화할 수 있다는 것을 알게 되었다. 아쉬운 점도 있었다. 오랫동안 맡아서 개발한 연결 파트 부분을 컨설팅 후 다른 방법으로 선회하라는 조언을 받고 기능을 아예 삭제하게 되었다. 그래도 이러한 과정을 겪으며 많은 것을 배우게 되었고 팀원들이 모두 각자 맡은 파트를 열심히 수행해 성공적으로 구현을 마무리할 수 있었고 목표한 제품을 완성했다는 점에 기쁨을 느꼈다. 열심히 노력한 팀원들에게 감사하단 말을 드리고 싶고 도움을 주신 조교님 교수님께도 감사의 말을 드리고 싶다. | ||
+ | |||
+ | |||
+ | 김*준 | ||
+ | : 이번 프로젝트는 다양한 경험과 배움으로 가득했고, 학기 동안 성장할 수 있는 기회가 되어 정말 뜻깊었다. 초기에는 과연 학기말까지 실제 구현을 할 수 있을까 걱정이 앞섰지만, 문제 원인을 분석해가며 하나씩 해결해가는 과정을 겪게 되면서 점차 목표에 가까워지는 희열을 느꼈다. 기존의 팀 프로젝트와는 달리, 파이썬과 코틀린이라는 파이썬과 코틀린이라는 서로 다른 프로그래밍 언어를 활용하고, 하드웨어와 소프트웨어를 연동하여 하나의 결과물을 제작하는 것이 이번 프로젝트의 새로운 도전이었다. 따라서 서버팀과 클라이언트팀으로 역할을 나누어 진행되었고, 개인별로도 담당 파트를 맡아 체계적인 분업을 이루었다. 이처럼 다른 영역의 역할을 나누며 팀워크를 형성해본 경험을 통해 의사소통의 중요성을 느낄 수 있었다. 나의 담당 역할 중 비중이 높았던 '졸음인식 딥러닝 모델 사용'과 처음 고안했던 '시저링크를 통한 높이조절 메카니즘' 부분이 여러 문제사항들로 인해 최종 모델에 쓰이지 못하였고, 이에 대해 개인적인 아쉬움과 팀원들에게 미안한 감정이 들었다. 그럼에도 불구하고 이번 기회를 통해 임베디드 시스템에 대한 이해도를 상승시키는 중요한 계기가 되었다. 라즈베리파이의 제한된 사양에서도 최적의 성능을 발휘할 수 있는 시스템을 구축하는것에 중점을 두었는데, 이를 통해 제약 조건 속에서도 최선의 해결책을 찾아내는 능력을 향상시킬 수 있었다. 또한 하드웨어의 한계에 부딪혔을 때 해결책을 찾아내는 과정은 쉽지 않았다. 그러나 고심 끝에 전혀 다른 방식으로 접근해보았고, 이를 통해 돌파구를 마련할 수 있었다. 이러한 경험을 통해 유연한 사고력과 문제 해결 능력의 중요성을 체득하게 되었다. 이번 프로젝트 기간 동안 전체적인 설계의 총괄을 맡아 리더십 있게 팀을 이끌어준 팀장과, 코틀린을 처음 배웠지만 완성도 높은 안드로이드 애플리케이션을 제작한 클라이언트 팀원들에게 감사의 말을 전하고 싶다. |
2023년 6월 20일 (화) 03:06 기준 최신판
프로젝트 소개
프로젝트 명
바른자세
프로젝트 기간
2022.3~2022.6
팀 소개
서울시립대학교 기계정보공학과 20174300** 정* (팀장)
서울시립대학교 기계정보공학과 20184300** 김*현
서울시립대학교 기계정보공학과 20184300** 김*준
서울시립대학교 기계정보공학과 20184300** 권*표
프로젝트 개요
1. 프로젝트 요약
본 프로젝트는 장시간의 집중시간을 편안한 자세로서 사용자에게 제공하는 것을 목표로 한다. 프로젝트는 모터를 통해 높이가 조절 되는 거치대를 기본으로 구성이 되어 있다. 이를 통해 사용자의 목과 팔꿈치의 부담을 줄이도록 해준다. 카메라를 통한 얼굴인식과 이를 이용한 알람 기능으로 사용자의 비집중 시간을 감지하여 알림을 제공한다. 프로젝트는 하드웨어를 제어하는 라즈베리파이 서버와 사용자의 입력을 기반으로 요청을 보내는 안드로이드 앱(클라이언트)으로 구성되어 있다. 서버와 클라이언트는 WiFi를 통해 1:1 TCP/IP통신을 한다. 사용자는 안드로이드 앱을 통해 높이 조절, 알람 시간 설정, 알람 모드 설정, 현재 촬영되는 영상 확인의 기능을 서버에게 요청할 수 있다. 또한 자신이 주로 사용하는 설정을 프로필을 만들어 저장하고, 불러올 수 있다. 서버는 클라이언트로부터 받은 요청을 바탕으로 하드웨어 제어를 하며 기능을 수행한다. 높이 조절 기능은 사용자가 요청한 높이로 모터를 제어하여 사용자가 요청한 높이로 거치대를 조절한다. 알람 기능을 사용자가 설정한 경우에는 카메라를 통해 사용자의 얼굴을 인식한다. 이 때 사용자의 얼굴이 인식되지 않으면, 사용자가 현재 집중을 하지 않고 있다고 판단하여, 시간을 측정한다. 측정한 시간이 알람 설정 시간이상이 되면 사용자가 요청한 알람 모드(소리, 진동)에 따라 알람을 제공한다. 사용자의 얼굴이 측정되지 않을 때는 LED 인디케이터를 통해 사용자에게 시작적인 알람을 제공한다. 이 때 사용자는 실제로 집중하고 있음에도 얼굴 인식이 되지 않고 있는 경우에는 자세를 바르게 하거나, 카메라 각도를 조절할 수 있게 된다. 서버는 사용자가 추가적인 요청을 보내면 현재 촬영 영상을 특정 웹주소를 통해 스트리밍한다.
2. 프로젝트의 배경 및 기대효과
가. 배경
- 현대에 이르러서는 근무 시간, 여가시간 등 다양한 이유로 장시간 책상을 이용하는 인원들이 증가하고 있다. 현재의 책상 이용 자세의 경우 머리와 목의 각도, 상완 외전 및 들어올림, 손목의 구부러짐과 신전 등 신체의 기능 구현에 있어 인체에 부담을 주고 있다. 그로 인해 VDT(Video Display Terminal)라 불리는 근골격계 질환을 겪는 현대인이 증가하고 있다.
가. 기대효과
- 책상에 앉아 장시간 업무를 진행 할 때 신체에 부담을 주는 자세를 개선하고 높은 집중 시간을 유지하는 데 도움이 되는 기구를 개발한다. 앱으로 사용자가 원하는 각도를 세밀하게 조정할 수 있고, 졸음 인식 기능과 알람 기능을 삽입하여 신체의 부담을 줄이고 효율성을 높인다.
3. 프로젝트 개발 목표
가. 기능성
- 강건성
- 본 시스템은 잦은 사용 빈도와 긴 사용 시간이 예상된다. 따라서 일정 시간 이상, 일정 반복 이후에도 정상적으로 동작해야한다. 높이 조절 기능을 위해 내구성 있는 구동부 설계가 필요하다. 서버로서 동시에 여러 프로세스가 구동하기 때문에 라즈베리 파이 프로세서의 성능안에서 오랜 시간 구동할 수 있는 서버를 설계해야한다.
- 정확성
- 제공하는 기능을 일관성 있게 사용자에게 제공할 수 있어야한다. 높이 조절, 얼굴 인식, 비집중 시간 기록 등 의도한 결과와 시스템의 구동이 일치해야한다.
- 반응성
- 사용자가 앱을 통해 입력하는 요청 사항이 서버에게 빠르게 전달되고, 그에 대한 서버의 응답 또는 동작이 빠르게 나타나여야 한다.
나. 경제성
- 간소화
- 본 제품은 비슷한 목적을 가진 시중제품과의 차별성과 스마트 가전 기구라는 특징과 함께, 실제 시장에서 경제성이 있도록 최대한 경제적인 부품 선정과 단순한 구조로 구현 해야 한다.
다. 편의성
- 직관성과 조작성
- 본 제품은 사용자 경험을 증가시키기위해 제품의 기능에 대한 직관성과 조작의 편의성을 갖추어야 한다. 이를 위하여 UX를 고려한 UI디자인을 진행할 것이다. 사용자는 앱을 통해 프로필 저장 기능을 사용할 수 있을 것이다. 프로필을 생성하면 그들의 책상 각도 설정을 쉽게 저장하고 불러올 수 있다. 이로 인해 사용자는 매번 책상 각도를 수동으로 조절하지 않을 수 있다. 또한, 여러 사용자가 동일한 책상을 공유하는 경우에도 각각의 프로필을 통해 쉽게 설정을 전환할 수 있다. LED 인디케이터와 앱 내 스트리밍 영상 덕분에 사용자는 비집중 감지의 동작 여부를 쉽게 확인할 수 있다. 알람을 통해 장시간의 비집중 시간이 감지된 사용자는 다시 집중할 수 있을 것이다.
동작 시나리오
역할분담 및 개발 일정
1. 역할분담
정*
[전체 진행 및 서버 시스템 개발 총괄, 통신 시스템 개발, 하드웨어 제어 시스템 개발, 회로도 설계]
프로젝트 진행 상황을 총괄하여 부품 구매 및 관리, 역할 분담 및 일정 조율을 수행했다. 프로젝트의 진행 방향을 정하고 팀 인원들의 개발 계획 및 결과를 시스템의 요구 사항과 비교하여 불가여부를 판단했다. 서버와 클라이언트의 통신 패킷의 설계했다. 서버 시스템에서 비집중 감지 모듈을 제외한 시스템을 구현했다. 라즈베리 파이의 GPIO제어를 위한 회로도와 시스템을 설계 및 개발 했다.
김*현
[앱 시스템 개발 총괄, 앱UI, 하드웨어 개발]
앱 시스템 개발팀을 총괄하여 진행 사항 공유 및 역할 분담을 수행했다. 앱의 UI 시나리오를 설계 하고 구현했다. 앱의 프로필 시스템을 설계하고 구현했다. 높이 조절 기능을 하는 구동부의 부품 설계를 진행했다.
김*준
[하드웨어 개발 총괄, 비집중 감지 모듈 개발, 영상 스트리밍 모듈 구현]
높이 조절 기능을 하는 구동부를 전체적으로 설계했다. 구동부의 부품을 설계하고 3D프린터를 통해 구현하는 과정을 총괄 했다. 카메라를 통해 사용자의 얼굴을 인식하고, 이를 통해 비집중 시간을 감지하는 모듈을 개발했다. 카메라의 영상을 특정 웹주소를 통해 Mjpeg over HTTP 방식으로 스트리밍 하는 모듈을 구현했다.
권*표
[사전 연결 개발 총괄 앱UI, 앱 WiFi 연결 개발, 스트리밍]
사전 연결 개발 부분을 구현했다. 앱 내부 WiFi 연결 및 서버 핫스팟 연결 과정을 진행했다. 같은 와이파이 내부에서 서버의 ip탐색을 설계했다. 웹 주소를 통한 앱 내부 스트리밍 기능을 구현하고 앱 구동 기능 및 UI를 개발했다.
2. 개발 일정
구현 내용
시스템 구성
- 본 시스템의 설계 구성도는 위와 같다. 클라이언트와 서버는 WiFi환경을 기반으로 TCP/IP 통신을 진행한다. 클라이언트의 요청을 서버는 연결된 기기를 제어하여 처리한다. 카메라를 통해 사용자 얼굴을 인식하여 비집중 감지, 영상 스트리밍 등의 기능을 수행한다. 사용자의 요청을 처리함에 따라 필요한 하드웨어 출력 장치를 선택하여 제어한다.
기구부 설계 및 구현
- 하드웨어의 최종 제품은 그림 4과 같이 설계하였고 전체적으로 상판, 선반 그리고 하판으로 이루어져 있다. 상판은 사용자가 물건을 올려놓고 사용하는 공간으로 노트북이나 태블릿과 같은 여러 물건을 올려놓고 작업할 수 있도록 충분한 크기인 800×550(mm) 크기로 제작했다. 두께는 12mm로 얇은 목재를 사용하여 상판자체의 무게를 줄였다. 또한 사용자의 팔꿈치가 몸의 중심보다 뒤로 가게 하여 어깨의 부담감을 줄일 수 있도록 중앙에 홈을 파여 디자인했다.
- 선반의 경우, 너비 길이는 상판과 경첩으로 부착되므로 상판과 같은 너비로 설계했다. 모터는 상판 연결부를 들어올리는 방식을 취하고 있으므로 책상면과 선반은 평행을 이루도록 설계하였다. 모터의 선반 받침대과 결합된 선반은 회전을 하지 않고 위아래로만 움직이며, 따라서 상판의 각도를 조절하는 역할을 수행하게 된다.
- 하판 위에는 장치들과 전선들을 배치하였고, 상단에 케이스를 가려 전체적으로 깔끔한 외관을 보여 완성도 있도록 설계하였다. 이때 하판의 높이를 최소화하기 위해서 가장 얇은 두께인 12mm 목재로 구매했다.
가. 각도 설계
- 프로젝트의 하드웨어 구성 요소 중 핵심 기능인 각도 조절 설계는 그림 A와 같이 진행하였다. 상판은 선반과 경첩을 이용해 고정되어 있으며, 이 구조를 통해 선반의 상승과 하강에 따라 상판과 바닥면 사이의 각도가 동적으로 변화하는 메커니즘을 구현하였다.
- 선반의 높이는 최저 각도에서 77mm로 설정되었고, 이때의 상판 기울기는 8.04°으로 측정되었다. 선반의 상승으로 인한 최대 높이는 172mm로 제한하였으며, 이 경우에는 상판의 기울기가 18.28°로 증가한다. 또한, 세밀한 각도 조절을 위해 높이 조절 단계는 총 20단계로 구성되어 있으며, 이는 각 단계마다 약 0.5°의 기울기 변화를 의미한다. 이와 같은 각도 조절 설계를 통해 사용자의 요구에 따라 동적인 선반 높이와 상판의 각도를 조절할 수 있다.
나. 높이 조절 구동부
- 선반의 수직 이동 기능은 스텝 모터와 모터 나사선에 고정된 선반 받침대를 통해 수행된다. 이 세 구성요소는 상호작용하여 선반의 상승과 하강을 구현한다. 선반 받침대의 상단면은 선반의 하단면과 밀착해 고정되어 있으며, 스텝 모터의 나사선은 하판에 수직으로 고정되어 있다. 이 스텝 모터의 나사선은 시계방향(CW)과 반시계방향(CCW)으로 양방향 회전이 가능하다. 따라서 스텝 모터의 시계 방향 회전 동작은 선반 받침대의 상승을 초래한다(그림 (a) 참조). 이는 모터의 회전 방향이 선반 받침대의 수직 움직임에 직접적으로 영향을 미치는 것을 보여준다. 반대로, 스텝 모터가 반시계 방향으로 회전할 때에는 선반 받침대가 하강한다(그림 (b) 참조). 따라서, 이러한 스텝 모터의 정교한 제어와 연동 구조는 선반의 수직 이동 기능의 핵심 요소로 작용한다.
다. 구동부 안정화 고정대
- 모터의 시계방향 및 반시계방향 구동 시 발생할 수 있는 상판의 진동을 제어하고, 선반의 회전 토크에 대응하기 위해 선반 양쪽 끝부분에 회전 방지 장치를 설치하였다, 위 그림은 모터의 양방향 회전에 대응하여 회전 고정대가 토크 방향을 안정화하는 과정을 시각적으로 나타내고 있다
제어부 및 회로 구현
- 본 프로젝트에서는 스피커, 진동 모터, LED, 모터 드라이버를 통한 모터, 카메라 등 다양한 디바이스를 사용한다. 실제 구동을 통해 알아낸 핀의 개수와 종류를 맞추어서 설계하였다. 프로젝트의 전체적인 완성도를 위해, 이들 디바이스를 하나의 통합된 시스템으로 구성하는 것에 중점을 두었다. 이를 위해 전체 시스템을 위한 회로도를 디자인하였다. 모터, 모터드라이버 와 나머지(LED,스피커,부저)를 구분지어 회로를 구성했다. 모터와 모터드라이버는 GPIO제어에 비해 더 많은 전력을 사용하기에 별도로 구성했다. pwm 신호를 사용하는 스피커, 진동모터는 하나의 pwm 출력을 회로를 통해 같이 받을 수 있도록 하였다. 전원 핀을 통해 둘 중 pwm신호를 받을 기기를 선택할 수 있도록 했다.
- 실제로 구현한 제어부 및 회로는 다음과 같다. 상판에 부착되는 LED와 부저는 연장 케이블로 연결될 수 있도록 하였다.
통신부 설계 및 구현
- 패킷의 설계에 앞서 HTTP 구조를 통해 패킷의 구성 요소 및 스펙을 참고했다. 경량 패킷으로서 파싱 및 내용 추가가 용이한 구조로 설계 했다. 통신의 안정성 검사를 위한 최소한의 헤더와 JSON형식을 이용한 패킷 바디로 이루어여있다. JSON의 key값은 숫자 인덱스를 사용하여 바디의 크기를 최적화했다. 위와 같은 패킷의 설계로, 서버와 클라이언트 TCP 통신을 안정적이게 진행 할 수 있었고, 통신 중에 평균 30~40byte의 패킷을 주고 받게 되었다. 각 패킷의 내용은 기본적으로 의미없는 기본값이 존재하며 서버는 이를 통해 불필요한 처리를 줄일 수 있다. 경량화를 위해 알람모드는 비트 마스크를 사용하였다.
- 헤더의 정보를 통해 패킷의 Body 길이를 알수 있다. 이를 이용해 body가 처음부터 끝까지 올바르게 왔는지 검사한다. 이 후 Body가 JSON형식인 것을 이용해 손쉽게 파싱한다.
소프트웨어 설계 및 구현
1. 라즈베리 파이 서버
서버 시스템은 WiFi 연결과 Listening Socket 생성을 하는 '서버 Listen' 단계와 클라이언트의 요청을 처리하는 '요청 처리' 두 부분으로 나뉜다.
1.1 서버 Listen
Ubuntu NetworkManager 패키지를 이용하여 사전에 정의된 WiFi에 연결합니다. 이후 TCP 서버 소켓을 만들고 클라이언트의 접속을 기다린다.
1.2 요청 처리
클라이언트의 요청이 담긴 패킷을 받고, 이를 파싱하여 그에 따른 동작을 수행하는 과정이다. 서버는 클라이언트에게 다음과 같은 4가지 기능을 제공한다:
- 모터 제어
- 모터 제어 프로세스는 사용자의 목표 단계가 담긴 queue를 받아, 이를 비울 때까지 모터를 제어하여 처리하는 동작을 한다. 서버는 사용자의 요청을 즉시 실행할 수 없을 때는 queue에 담고, 실행 가능할 때 q를 복사하여 위의 모터 제어 동작을 하는 프로세스를 생성한다. 그러나 서버의 패킷 파싱 이후 모터 제어 프로세스 생성 유무를 결정하기 때문에, 기존의 모터 제어 프로세스가 종료 후, 새로운 요청이 도착해야만 q에 담긴 요청이 실행되는 문제가 있다.
- 비집중 시간 감지 및 알람
- 서버는 사용자가 알람 관련 기능을 설정하면, 비집중 감지 프로세스를 생성한다. 감지 프로세스는 사용자가 얼굴이 인식되지 않는 상황을 비집중 시간이라고 판단한다. 비집중이 인식되면 LED를 통해 경고한다. 측정 결과에 따라 ’집중‘, ’비집중‘ 두가지 상태로 구분한다. 바로 전 프레임의 상태를 저장하고, 이를 현 프레임과 비교한다. 만약 상태가 달라지면 달라지는 시점을 저장한다. 이후 가장 최근에 기록한 시점으로부터 경과한 시간이 알람 시간보다 크고, 현재 상태가 ’비집중 상태‘라면 알람 모드에 따라 알람을 울린다.
- 영상 스트리밍
- 사용자의 얼굴 인식 결과 영상을 특정 웹주소를 통해 Mjpeg over HTTP 방식으로 계속해서 스트리밍 한다. Flask 프레임 워크를 이용하여 구현했다. 해당 기능을 python을 통해 실행하는데, 이때 rasberry Pi 프로세스에게 큰 부하가 발생한다. 따라서 10분 이상 동작하면 프로세스의 쓰로틀링을 유발하고, 서버의 처리 속도가 매우 늦어지거나 혹은 라즈베리 파이가 종료 될 수 있는 문제점이 있다.
- 전원 제어
- 자원 회수 이후 OS의 종료기능을 이용하여 라즈베리 파이를 종료시킨다. 처음으로 소켓을 모두 닫는다. 이후 모터 제어를 통해 기기 상태를 초기화 한다. 이후 초기화가 끝나면 프로세스를 차례로 종료 시킨 후, Process 객체를 반환한다. 이후 공유 메모리 공간을 반환한다. 자원회수가 끝난 후에는 os 명령어를 이용해 라즈베리 파이를 종료 시킨다. 따라서 라즈베리파이가 아닌 독립적으로 전력을 공급받는 모터와 모터 드라이버는 종료하지 못한다는 문제점이 있다.
2. 안드로이드 app 클라이언트
클라이언트 시스템은 WiFi연결 및 Socket 통신 준비 단계와 프로필 저장값을 토대로 앱 실행 시 소켓을 전달하는 초기값 전달 단계, 입력에 따른 통신 단계로 나뉜다.
2.1 앱 UI
- ’홈 화면‘의 경우 사용자가 설정한 프로필 인자들을 확인할 수 있고 프로필 추가, 프로필 변경, 전원끄기, 영상확인 버튼을 눌러 해당 기능들을 수행할 수 있다. 프로필 추가 및 변경, 영상 확인 버튼을 누르게 되면 해당 기능을 수행하는 화면으로 이동하고 전원 끄기 버튼을 누르면 서버로 종료 요청을 보낸다.
- ’높이 조절 화면‘의 경우 사용자가 직접 입력하거나 상, 하 버튼을 이용하여 설정한 단계를 서버로 보내고 해당하는 단계를 사용자가 볼 수 있도록 구현하였다. 또한 단계 저장 버튼을 누르면 현재 단계값을 사용자의 최적 단계로 저장한다.
- ’알람 설정 화면‘의 경우 알람을 키거나 끌 수 있고 키는 경우 알람시간과 알람모드를 설정할 수 있게 구현하였다. 설정 저장 버튼을 누르는 경우 해당 값들을 현재 선택된 프로필에 저장한다.
- '프로필 추가 화면'은 사용자의 편의를 위해 프로필을 추가하는 화면으로 이름, 알람 관련 사용자 설정을 프로필에 추가하고 저장한다.
- '프로필 목록 화면'은 사용자가 기존에 저장한 프로필의 목록을 나타내며 이 중 사용하고 싶은 프로필은 선택 버튼을 누르면 되고 삭제하고 싶은 경우 삭제 버튼을 누르면 된다.
- '스트리밍 화면'은 사용자가 영상 확인 버튼을 누를 경우 나타나며 기기에 연결된 카메라에서 송출되는 영상이 출력된다. 영상이 로딩되는 동안 로딩 바가 나타나며 close 버튼을 누르면 영상이 종료되고 홈 화면으로 돌아간다.
2.2 WiFi 연결
사전에 사용자로부터 입력받은 WiFi에 연결한 후, 소켓 통신을 통해 서버에 해당 와이파이의 SSID와 비밀번호를 패킷 형식으로 보낸 뒤 동일한 WiFi에 연결된 서버의 IP Address와 사전에 결정한 포트번호로부터 소켓 통신을 진행한다.
2.3 초기값 전달
소켓 통신이 정상적으로 진행되는 경우 앱 실행 시 프로필 값을 토대로 서버에 패킷을 보낸다. 이는 설정해놓은 프로필 값에 따라 스트리밍 서버 동작 여부가 결정되기 때문이다.
2.4 프로필 설정 및 입력에 따른 통신
프로필을 추가, 변경 및 삭제하거나 사용자가 입력에 해당하는 버튼을 누르는 경우 이를 패킷화 시키고 서버에 보내는 과정이다. 패킷을 보내는 주기가 너무 빨라지는 경우 socket을 bind하는 과정에 문제가 생길 수 있기 때문에 서버의 응답을 받기 전까지 대기화면을 출력한다. 또한 서버의 응답을 스트리밍 주소로 받는 경우, 스트리밍된 주소로 이동하여 사용자에게 영상을 제공한다.
- 프로필
- 앱을 실행했을 때 기존에 선택해놓은 프로필이 있는 경우, Kotlin에서 제공하는 SharedPreference 기능(앱 내부 데이터 사용)을 사용하여 해당 프로필의 알람 시간과 알람 모드에 해당하는 값을 패킷화시킨다. 이렇게 만들어진 패킷을 서버로 보내 스트리밍 서버 동작 여부를 결정한다. 프로필이 없는 경우에는 데이터를 저장하는 것에 대한 불편함이 생길 수 있기 때문에 프로필 추가 화면으로 이동하도록 설정하였다.
- 전원 끄기, 카메라 화면 확인
- 홈 화면에서 전원끄기 버튼을 누르는 경우 패킷의 전원 인자를 수정하여 서버에 보낸다. 서버는 전원인자가 수정되는 것을 확인하고 서버를 종료한다. 카메라 확인 버튼을 누르는 경우 스트리밍 화면으로 넘어가 패킷의 스트리밍 인자를 수정하고 서버에 보내면 서버로부터 스트리밍 주소를 받아 화면에 출력하게 된다. 이후 닫기 버튼을 누르게 되면 스트리밍 요청인자를 원래 기본값으로 수정하여 스트리밍 서버를 종료시킨다.
- 높이 조절, 알람설정
- 높이 조절과 알람 설정 기능의 경우 각각 높이 조절 화면, 알람 설정 화면에서 구현된다. 높이 조절의 경우 사용자가 입력값을 입력하거나 높낮이 버튼을 눌러 패킷의 높이 조절 인자를 수정하고 서버로 보내 모터의 높낮이를 조절한다. 조절된 높낮이는 화면에 표시되며 최적 단계 저장 버튼을 통해 이를 프로필 값에 저장할 수 있다.
- 알람 설정의 경우 알람 시간과 알람 모드를 입력값 및 버튼으로 설정한 뒤에 저장 버튼을 누르면 현재 선택된 프로필 인자를 입력한 값으로 수정하고 그에 따라 패킷을 수정하여 서버로 보낸다.
프로젝트 결과
최종 결과물
결과물 사진
영상 링크
프로필 추가 및 각도 조정 :https://www.youtube.com/watch?v=9ePsnrU0e_o
멀티 프로세싱 ( 각도 조정하면서 스트리밍 영상 확인 ) : https://www.youtube.com/watch?v=IZEqMqtJtLg
전원 끄기 : https://www.youtube.com/watch?v=96WSgqh2PZo
미구현 내용
사전 연결
사전 연결 과정은 앱에서 WiFi 이름과 비밀번호를 입력받은 뒤 앱 내부 데이터에 저장 후 라즈베리 파이의 hotspot에 연결하고 WiFi 이름, 비밀번호 데이터를 라즈베리 파이에 보내고 각각 앱과 라즈베리 파이가 해당 데이터를 통해 같은 WiFI에 접속한 뒤 앱에서 라즈베리 파이의 ip를 탐색 후 소켓 연결을 하는 과정이었다.
WiFi 데이터를 라즈베리 파이 hotspot에 접속한 후 패킷을 통해 데이터를 전송하고 서로 같은 WiFi 연결에 연결하는 것은 성공하였으나 이후 라즈베리 파이의 ip 주소를 찾는 부분에서 문제가 발생하였다. 라즈베리 파이 주소를 찾기 위해서 같은 WiFi 주소 내에서 ip suffix 부분을 바꿔가면서 ping 명령어를 보내고 응답 메시지를 받는 방법을 시도하였다. 하지만 WiFi 내에 다른 기기가 네트워크에 연결되어있는 경우 다른 기기 또한 응답을 보낼 수 있어 라즈베리 파이의 IP 주소를 특정할 수 없었으며 통신하는 데 어려움이 발생하였다. 또한 특정 공유기에서는 네트워크 방화벽 구성에 의해 ICMP ping 요청이 차단되어 정확한 IP 주소를 확인할 수 없는 경우가 발생하였다. 따라서 ip 주소를 일일이 찾아가는 방법을 구현하지 않고 고정 ip를 사용하는 방법으로 바꾸었다.
프로젝트 평가
평가항목 및 결과
설문조사 내용
위의 설문지를 바탕으로 시연을 해본 사용자들에게 설문을 진행하였다.
결과 분석
사용성 측면에서는 긍정적인 답변을 받았다. 그러나 차후 사용 의향에서 낮은 점수를 받았는데, 모터의 소음이 가장 큰 원인으로 생각된다. 또한 기타 의견으로는 하드웨어 구조적 문제가 눈에 띄었다. 현재 상판은 모터의 축에만 고정되어 있다. 따라서 실사용에 불편함이 존재하기 때문이라고 생각된다.
느낀점
정*
- 팀장을 맡게 되었을 때 현대 프로그래밍 기법에 대한 책을 읽었었고, 이를 실제로 활용하고 싶었다. 우선적인 시스템 설계와 흐름도를 통한 가구현. 그것을 바탕으로한 개발 업무 분리 및 테스트 케이스 설정. 팀 별 코딩 규칙 등 효율적인 팀 개발을 위해 새로운 작업 방식과 기법을 도입했다. 우선 처음 접해본 개념에 혼란스러웠을텐데도 잘 따라와준 팀원들에게 감사의 말을 전하고 싶다. 시스템의 요구사항과 스펙을 정하고 사전에 문제점을 미리 파악해가며 설계를 진행했기 때문에, 시간 대비 더욱 효율적인 개발이 가능했던 것 같다. 이렇게 완성된 프로그램은 구현에서 선택한 요인들이 모두 합리적인 이유를 가지고 있었으며, 결과적으로 개발 시간 대비 효율적인 구조를 가지면서 높은 안정성, 확장성을 가진 서버를 개발할 수 있었다. 현대 프로그래밍 기법이 왜 중요한지, 그에 대한 효능을 몸소 체험할 수 있었다. 더욱 더 많이 연습하며 능숙해져야겠다고 생각할 수 있었다. 하드웨어 부분에서 경험자가 없다보니 많은 난관이 있었다.그럴 때마다 다같이 토의를 하며 해결할 수 있었지만 기구학을 고려한 설계는 경험이 매우 중요하다는 것을 배울 수 있었다.
김*현
- 학부에서 배운 내용을 실제로 적용해볼 기회가 드물고 이에 대한 아쉬움이 항상 있었는데 임베디드시스템이라는 과목에서 그 아쉬움이 적지 않게 해소되었던 것 같다. 물론 하드웨어를 설계하고 구현하는 과정과 앱 개발 과정에서 시행착오도 많이 겪고 어려움을 많이 느끼기도 하였다. 특히 처음 시도해보는 앱 개발의 경우 한 학기 안에 코틀린에 대한 기초적인 문법 공부부터 실제 환경에서 버그 없이 잘 작동하는 앱을 만들기까지의 과정이 쉽지는 않았지만 핸드폰에 설치해서 기능 하나하나가 잘 구현되는 것을 보는 재미가 더 컸기 때문에 끝까지 앱 개발을 진행할 수 있었고 성공적으로 잘 마무리할 수 있었던 것 같다. 또한 중간에 원래 계획했던 내용이나 개발 중이였던 기능을 시간 상 제외시켰던 경우도 있었으나 결과적으로 이러한 과정이 있었기 때문에 완성도 높은 제품을 만들 수 있다는 것을 직접 체감해볼 수 있었다. 마지막으로 이 과정을 큰 마찰 없이 마무리한 배울 점 많은 팀원들, 막막할 때마다 도움을 주신 교수님과 조교님들께 감사하다는 말을 전하고 싶다.
권*표
- 과의 특성에 맞게 기계와 소프트웨어를 융합하는 방법을 처음으로 겪어보는 시간이었다. 이번 임베디드 시스템 프로젝트에서 가장 큰 도전은 하드웨어와 소프트웨어를 효율적으로 통합하는 것이었다. 이러한 설계를 진행하면서 하드웨어의 성능, 제약 사항, 인터페이스 등을 이해하고 소프트웨어와 원활하게 통신하는 방법을 찾아야 했다. 프로젝트를 진행하면서 하드웨어와 소프트웨어를 밑에서 부터 설계하는 것이 굉장히 어려운 것이라는 것을 느꼈다. 또한 이러한 통합 작업은 시간과 노력이 많이 필요하지만, 정확한 통합을 통해 최종 제품의 성능을 극대화할 수 있다는 것을 알게 되었다. 아쉬운 점도 있었다. 오랫동안 맡아서 개발한 연결 파트 부분을 컨설팅 후 다른 방법으로 선회하라는 조언을 받고 기능을 아예 삭제하게 되었다. 그래도 이러한 과정을 겪으며 많은 것을 배우게 되었고 팀원들이 모두 각자 맡은 파트를 열심히 수행해 성공적으로 구현을 마무리할 수 있었고 목표한 제품을 완성했다는 점에 기쁨을 느꼈다. 열심히 노력한 팀원들에게 감사하단 말을 드리고 싶고 도움을 주신 조교님 교수님께도 감사의 말을 드리고 싶다.
김*준
- 이번 프로젝트는 다양한 경험과 배움으로 가득했고, 학기 동안 성장할 수 있는 기회가 되어 정말 뜻깊었다. 초기에는 과연 학기말까지 실제 구현을 할 수 있을까 걱정이 앞섰지만, 문제 원인을 분석해가며 하나씩 해결해가는 과정을 겪게 되면서 점차 목표에 가까워지는 희열을 느꼈다. 기존의 팀 프로젝트와는 달리, 파이썬과 코틀린이라는 파이썬과 코틀린이라는 서로 다른 프로그래밍 언어를 활용하고, 하드웨어와 소프트웨어를 연동하여 하나의 결과물을 제작하는 것이 이번 프로젝트의 새로운 도전이었다. 따라서 서버팀과 클라이언트팀으로 역할을 나누어 진행되었고, 개인별로도 담당 파트를 맡아 체계적인 분업을 이루었다. 이처럼 다른 영역의 역할을 나누며 팀워크를 형성해본 경험을 통해 의사소통의 중요성을 느낄 수 있었다. 나의 담당 역할 중 비중이 높았던 '졸음인식 딥러닝 모델 사용'과 처음 고안했던 '시저링크를 통한 높이조절 메카니즘' 부분이 여러 문제사항들로 인해 최종 모델에 쓰이지 못하였고, 이에 대해 개인적인 아쉬움과 팀원들에게 미안한 감정이 들었다. 그럼에도 불구하고 이번 기회를 통해 임베디드 시스템에 대한 이해도를 상승시키는 중요한 계기가 되었다. 라즈베리파이의 제한된 사양에서도 최적의 성능을 발휘할 수 있는 시스템을 구축하는것에 중점을 두었는데, 이를 통해 제약 조건 속에서도 최선의 해결책을 찾아내는 능력을 향상시킬 수 있었다. 또한 하드웨어의 한계에 부딪혔을 때 해결책을 찾아내는 과정은 쉽지 않았다. 그러나 고심 끝에 전혀 다른 방식으로 접근해보았고, 이를 통해 돌파구를 마련할 수 있었다. 이러한 경험을 통해 유연한 사고력과 문제 해결 능력의 중요성을 체득하게 되었다. 이번 프로젝트 기간 동안 전체적인 설계의 총괄을 맡아 리더십 있게 팀을 이끌어준 팀장과, 코틀린을 처음 배웠지만 완성도 높은 안드로이드 애플리케이션을 제작한 클라이언트 팀원들에게 감사의 말을 전하고 싶다.