AiCane은 시각장애인과 보행약자를 위한 AI 자율주행 지팡이입니다.
📝 슈도코드: 메인 프로그램 시작
함수 메인_프로그램_시작():
// 1단계: 하드웨어 준비
출력 "하드웨어 초기화 중..."
만약 (아두이노_연결() 실패):
출력 "아두이노 연결 실패 - 프로그램 종료"
종료
만약 (라이다_연결() 실패):
출력 "LiDAR 없이 진행합니다"
출력 "카메라 준비 중... (5초 대기)"
5초_대기()
// 2단계: 소프트웨어 시스템 준비
오도메트리_초기화() // 위치 추적 시스템
상태기계_초기화() // 로봇 행동 제어
미션시스템_초기화() // 명령 실행 시스템
목표탐색_초기화() // 자율 주행 시스템
// 3단계: 사용자에게 모드 선택 받기
반복:
메뉴_보여주기()
사용자_선택 = 입력_받기()
만약 (사용자_선택 == "1"):
자유탐색_모드_실행()
아니면 만약 (사용자_선택 == "2"):
미션주행_모드_실행()
아니면 만약 (사용자_선택 == "3"):
목표탐색_모드_실행()
아니면 만약 (사용자_선택 == "종료"):
멈춤
// 4단계: 깨끗하게 종료
모든_모터_정지()
카메라_종료()
라이다_종료()
아두이노_통신_종료()
출력 "프로그램 종료 완료"
🔍 설명:
📝 슈도코드: 자유 탐색 - 장애물을 피하며 자유롭게 돌아다니기
함수 자유_탐색_한_스텝():
// 1단계: 사람이 있는지 확인 (안전 최우선!)
만약 (카메라에_사람_감지됨):
즉시_정지()
출력 "사람 감지 - 멈춤"
돌아가기
// 2단계: 센서로 장애물 확인
전방_센서 = 초음파_센서_읽기()
왼쪽_센서 = 적외선_왼쪽_읽기()
오른쪽_센서 = 적외선_오른쪽_읽기()
// 3단계: 막다른 골목인지 체크
만약 (전방_막힘 AND 왼쪽_막힘 AND 오른쪽_막힘):
출력 "막다른 골목 발견!"
0.6초_동안_후진()
정지()
1.0초_동안_180도_회전()
정지()
돌아가기
// 4단계: 장애물이 있으면 회피
만약 (전방_막힘 OR 왼쪽_막힘 OR 오른쪽_막힘):
회피_카운터 = 회피_카운터 + 1
만약 (회피_카운터 >= 5): // 5번 연속 회피했다면
출력 "계속 막히네요 - 큰 회전으로 방향 전환"
0.5초_동안_후진()
0.8초_동안_왼쪽으로_회전()
회피_카운터 = 0
돌아가기
// 일반 회피 동작
만약 (전방_막힘):
만약 (라이다_사용가능):
빈_공간_방향 = 라이다로_빈_공간_찾기()
만약 (빈_공간이_왼쪽):
0.4초_후진()
0.5초_왼쪽_회전()
아니면:
0.4초_후진()
0.5초_오른쪽_회전()
아니면:
// 라이다 없으면 기본 왼쪽 회피
0.4초_후진()
0.5초_왼쪽_회전()
아니면 만약 (왼쪽_막힘):
0.3초_오른쪽으로_이동()
아니면 만약 (오른쪽_막힘):
0.3초_왼쪽으로_이동()
정지()
돌아가기
// 5단계: 장애물이 없으면 정상 주행
회피_카운터를_천천히_감소()
// 카메라로 바닥의 자유공간 찾기
프레임 = 카메라_이미지_가져오기()
중심선_오프셋 = 자유공간_중심_계산(프레임)
만약 (중심선_오프셋이_계산_안됨):
천천히_직진() // 비전 실패 시 안전 모드
돌아가기
// 중심선에 맞춰 방향 조정
만약 (오프셋이_거의_0):
정상_속도로_직진()
아니면 만약 (오프셋이_매우_큼):
만약 (오른쪽으로_많이_벗어남):
0.15초_오른쪽_회전()
아니면:
0.15초_왼쪽_회전()
약간_느리게_직진()
아니면: // 오프셋이 작음
만약 (오른쪽으로_조금_벗어남):
0.1초_오른쪽_회전()
아니면:
0.1초_왼쪽_회전()
정상_직진()
🔍 설명:
📝 슈도코드: 미션 주행 - 정해진 경로 따라가기
// 예시 미션: "2m 전진 → 90도 좌회전 → 1.5m 전진"
함수 미션_로드하기(미션_목록):
출력 "미션을 불러옵니다:"
각 명령 in 미션_목록:
출력 명령
현재_단계 = 0
미션_상태 = "대기중"
함수 미션_한_스텝_실행():
// 1단계: 장애물 체크 (안전 우선)
만약 (장애물_있음):
만약 (현재_정상_주행중):
출력 "장애물 발견 - 회피 시작"
회피_전_위치_저장()
미션_상태 = "회피중"
장애물_회피_동작()
돌아가기
// 2단계: 현재 미션 단계 실행
만약 (미션_상태 == "정상_실행중"):
현재_명령 = 미션_목록[현재_단계]
만약 (현재_명령이_"전진" 또는 "후진"):
직선_이동_실행(현재_명령)
아니면 만약 (현재_명령이_"회전"):
회전_실행(현재_명령)
만약 (현재_명령_완료됨):
출력 "단계 완료!"
현재_단계 = 현재_단계 + 1
만약 (현재_단계 >= 미션_총_단계수):
출력 "🎉 미션 완료!"
미션_상태 = "완료"
모터_정지()
아니면 만약 (미션_상태 == "회피중"):
// 회피 완료 후 원래 경로로 복귀
미션_상태 = "복귀중"
원래_경로로_돌아가기()
아니면 만약 (미션_상태 == "복귀중"):
출력 "원래 경로로 복귀 완료 - 미션 재개"
미션_상태 = "정상_실행중"
함수 직선_이동_실행(명령):
목표_거리 = 명령.거리
// 처음 실행할 때만 시작 위치 기록
만약 (시작_위치가_없음):
시작_위치 = 현재_로봇_위치()
// 현재까지 얼마나 이동했는지 계산
현재_위치 = 현재_로봇_위치()
이동한_거리 = 시작_위치부터_현재_위치까지_거리()
// 목표에 도달했는지 확인
만약 (이동한_거리 >= 목표_거리):
모터_정지()
명령_완료_표시()
출력 "이동 완료: " + 이동한_거리 + "m"
아니면:
// 계속 이동
만약 (명령이_"전진"):
전진_모터_구동()
아니면:
후진_모터_구동()
함수 회전_실행(명령):
목표_각도 = 명령.각도
만약 (시작_각도가_없음):
시작_각도 = 현재_로봇_방향()
현재_각도 = 현재_로봇_방향()
회전한_각도 = 현재_각도 - 시작_각도
만약 (회전한_각도 >= 목표_각도):
모터_정지()
명령_완료_표시()
출력 "회전 완료: " + 회전한_각도 + "도"
아니면:
만약 (명령이_"좌회전"):
왼쪽_회전_모터_구동()
아니면:
오른쪽_회전_모터_구동()
함수 장애물_회피_동작():
출력 "회피 동작 시작"
// 1. 후진
0.5초_후진()
정지()
// 2. 라이다로 빈 공간 찾기
만약 (라이다_사용가능):
빈_공간_방향 = 라이다로_가장_넓은_공간_찾기()
만약 (빈_공간이_왼쪽):
0.4초_왼쪽_회전()
아니면:
0.4초_오른쪽_회전()
아니면:
// 라이다 없으면 기본 왼쪽
0.4초_왼쪽_회전()
// 3. 옆으로 이동
0.4초_옆으로_이동()
정지()
출력 "회피 완료"
함수 원래_경로로_돌아가기():
출력 "원래 위치로 복귀 중..."
목표_X = 회피_전_위치.X
목표_Y = 회피_전_위치.Y
목표_방향 = 회피_전_위치.방향
현재_위치 = 현재_로봇_위치()
남은_거리 = 목표까지_거리(목표_X, 목표_Y)
만약 (남은_거리 > 0.5미터):
// 목표 방향으로 회전
목표_상대각도 = 목표_방향_계산(목표_X, 목표_Y)
만약 (각도차이가_큼):
회전하여_방향_맞추기()
// 접근
0.5초_전진()
정지()
// 방향 보정
현재_방향 = 현재_로봇_방향()
방향_차이 = 목표_방향 - 현재_방향
만약 (방향_차이가_큼):
회전하여_방향_맞추기()
출력 "복귀 완료"
🔍 설명: