🦾 AiCane 프로젝트 - 핵심 기능 슈도코드 가이드

📌 프로젝트 개요

AiCane은 시각장애인과 보행약자를 위한 AI 자율주행 지팡이입니다.


🎯 1. 메인 프로그램 실행 흐름 (main_v2.py)

📝 슈도코드: 메인 프로그램 시작

함수 메인_프로그램_시작():
    // 1단계: 하드웨어 준비
    출력 "하드웨어 초기화 중..."
    
    만약 (아두이노_연결() 실패):
        출력 "아두이노 연결 실패 - 프로그램 종료"
        종료
    
    만약 (라이다_연결() 실패):
        출력 "LiDAR 없이 진행합니다"
    
    출력 "카메라 준비 중... (5초 대기)"
    5초_대기()
    
    // 2단계: 소프트웨어 시스템 준비
    오도메트리_초기화()      // 위치 추적 시스템
    상태기계_초기화()        // 로봇 행동 제어
    미션시스템_초기화()      // 명령 실행 시스템
    목표탐색_초기화()        // 자율 주행 시스템
    
    // 3단계: 사용자에게 모드 선택 받기
    반복:
        메뉴_보여주기()
        사용자_선택 = 입력_받기()
        
        만약 (사용자_선택 == "1"):
            자유탐색_모드_실행()
        아니면 만약 (사용자_선택 == "2"):
            미션주행_모드_실행()
        아니면 만약 (사용자_선택 == "3"):
            목표탐색_모드_실행()
        아니면 만약 (사용자_선택 == "종료"):
            멈춤
    
    // 4단계: 깨끗하게 종료
    모든_모터_정지()
    카메라_종료()
    라이다_종료()
    아두이노_통신_종료()
    출력 "프로그램 종료 완료"

🔍 설명:


🚶 2. 자유 탐색 모드 (fsm_v2.py - EXPLORE Mode)

📝 슈도코드: 자유 탐색 - 장애물을 피하며 자유롭게 돌아다니기

함수 자유_탐색_한_스텝():
    // 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초_왼쪽_회전()
        정상_직진()

🔍 설명:


🎯 3. 미션 주행 모드 (mission.py)

📝 슈도코드: 미션 주행 - 정해진 경로 따라가기

// 예시 미션: "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초_전진()
        정지()
    
    // 방향 보정
    현재_방향 = 현재_로봇_방향()
    방향_차이 = 목표_방향 - 현재_방향
    
    만약 (방향_차이가_큼):
        회전하여_방향_맞추기()
    
    출력 "복귀 완료"

🔍 설명: