Created
December 12, 2017 11:45
-
-
Save jjangga0214/8068b87b8d8c57ca8128566ed40732c6 to your computer and use it in GitHub Desktop.
4조의 창연공 보고서를 위한 파일 간단 설명
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import RPi.GPIO as GPIO | |
GPIO.setwarnings(False) | |
GPIO.setmode(GPIO.BOARD) | |
import time | |
import multiprocessing as mp | |
import rcar # 구동체의 움직임에 대한 기능을 담고 있는 코드이다. | |
import sensors # 센서들의 기능을 담고 있는 코드이다. | |
class Config: | |
LINEAR_SPEED = 60 | |
TURNING_SPEED = 100 | |
def find_line_if_out(): | |
''' | |
라인트레이싱 중 라인을 벗어났을 경우 작동된다. | |
라인을 벗어나기 직전 라인의 왼쪽에 있었다면 (_last_valid_pos == 1.0) 우회전하고, | |
라인을 벗어나기 직전 라인의 오른쪽에 있었다면 (_last_valid_pos == -1.0) 좌회전하고, | |
라인을 벗어나기 직전 라인의 중앙에 있었다면 다시(_last_valid_pos == 0.0) 좌회전한다. | |
''' | |
while rcar.FRONTINFRA.decide() == sensors.InfraRedSensor.Position.OUT: | |
last_valid_pos = rcar.FRONTINFRA.last_valid_pos | |
if last_valid_pos == sensors.InfraRedSensor.Position.LEFT: | |
print("rpointturn함") | |
rcar.rpointturn(100, sec=0.1, stop=True) | |
elif last_valid_pos == sensors.InfraRedSensor.Position.RIGHT: | |
print("lpointturn함") | |
rcar.lpointturn(100, sec=0.1, stop=True) | |
else: | |
print("_last_valid_pos 이 LEFT도 RIGHT 도 아님") | |
rcar.lpointturn(100, sec=0.04, stop=True) | |
class ArrivalException(Exception): | |
''' | |
도착선에 도달시 raise 된다. | |
''' | |
pass | |
def strace(): | |
''' | |
주행하는 메서드이다. | |
''' | |
rightpos = rcar.RIGHTINFRA.decide() | |
for i in range(15): | |
''' | |
앞의 적외선 센서에 5개의 불이 모두 들어오면 교차로이거나 도착선에 도착한 것이다. | |
15번 이상 이런 경우가 누적되고, 오른쪽 적외선 센서에도 모두 불이 들어온다면 ArrivalException 을 raise 한다. | |
''' | |
time.sleep(0.01) | |
if rcar.FRONTINFRA.decide() != sensors.InfraRedSensor.Position.ARRIVAL: | |
break # python 문법 설명 : break 가 실행되면 아래의 else 문은 실행되지 않는다. | |
else: # python 문법 설명 : 만일 위에서 break 문이 실해되지 않고 정상적으로 for 문이 끝까지 실행된다면 else 문이 실행된다. | |
if rightpos == sensors.InfraRedSensor.Position.ARRIVAL: | |
raise ArrivalException | |
# 오른쪽 적외선 센서의 실제 상대 위치 값 | |
rightpos = rcar.RIGHTINFRA.decide() | |
frontpos, is_on_threshold = rcar.FRONTINFRA.escaping_decide() | |
if rightpos != sensors.InfraRedSensor.Position.OUT \ | |
and frontpos == sensors.InfraRedSensor.Position.LEFT: | |
''' | |
오른쪽 센서가 감지되면 구동체를 멈춘다. | |
''' | |
rcar.stop() | |
for i in range(1000): | |
''' | |
안전코드 : 정말 오른쪽 센서가 라인위에 있는지 안전하게 확인한다. | |
''' | |
rightpos = rcar.RIGHTINFRA.decide() | |
if rightpos == sensors.InfraRedSensor.Position.OUT \ | |
or frontpos != sensors.InfraRedSensor.Position.LEFT: | |
return | |
while rightpos != sensors.InfraRedSensor.Position.OUT: | |
''' | |
오른쪽 센서가 라인 위에 있지 않을 때까지 rpoint 턴 한다. | |
''' | |
rightpos = rcar.RIGHTINFRA.decide() | |
rcar.rpointturn(100, sec=0.03, stop=True) | |
print('here rpoint by rp') | |
rcar.stop() | |
frontpos, is_on_threshold = rcar.FRONTINFRA.escaping_decide() | |
''' | |
앞의 적외선 센서의 상태이다. | |
frontpos 는 LEFT, RIGHT 등 Position 값이다. | |
is_on_threshold 가 True면 급격한 회전이 필요하고, False면 부드러운 회전을 한다. | |
''' | |
if frontpos == sensors.InfraRedSensor.Position.OUT: | |
rcar.stop() | |
for i in range(1000): | |
''' | |
정말로 OUT 인 상태가 맞는지 1000번 확인하는 안전코드 | |
''' | |
frontpos, is_on_threshold = rcar.FRONTINFRA.escaping_decide() | |
if frontpos != sensors.InfraRedSensor.Position.OUT: | |
return | |
# 정말 OUT이 맞으면 find_line_if_out() 를 호출해 라인으로 복귀한다. | |
find_line_if_out() | |
elif frontpos == sensors.InfraRedSensor.Position.MIDDLE: | |
rcar.forward(Config.LINEAR_SPEED, sec=0.01, stop=True) | |
elif frontpos == sensors.InfraRedSensor.Position.LEFT: | |
rcar.stop() | |
for i in range(1000): | |
''' | |
정말로 LEFT 인 상태가 맞는지 10번 확인하는 안전코드 | |
''' | |
frontpos, is_on_threshold = rcar.FRONTINFRA.escaping_decide() | |
if frontpos != sensors.InfraRedSensor.Position.LEFT: | |
return | |
if is_on_threshold: | |
rcar.forward(Config.LINEAR_SPEED, sec=0.05, stop=True) | |
rcar.rpointturn(Config.TURNING_SPEED, sec=0.09, stop=True) | |
else: | |
rcar.rcurveturn(Config.TURNING_SPEED, ratio=0.25, sec=0.01, stop=True) | |
elif frontpos == sensors.InfraRedSensor.Position.RIGHT: | |
rcar.stop() | |
for i in range(1000): | |
''' | |
정말로 RIGHT 인 상태가 맞는지 10번 확인하는 안전코드 | |
''' | |
frontpos, is_on_threshold = rcar.FRONTINFRA.escaping_decide() | |
if frontpos != sensors.InfraRedSensor.Position.RIGHT: | |
return | |
if is_on_threshold: | |
rcar.forward(Config.LINEAR_SPEED, sec=0.05, stop=True) | |
rcar.lpointturn(Config.TURNING_SPEED, sec=0.09, stop=True) | |
else: | |
rcar.lcurveturn(Config.TURNING_SPEED, ratio=0.25, sec=0.01, stop=True) | |
else: | |
pass | |
rcar.FRONTINFRA.update_pos(frontpos) | |
if __name__ == '__main__': | |
''' | |
멀티 프로세싱 start | |
일반적으로 쓰레드(다른 컴파일 언어에서의 쓰레드듣 파이썬의 멀티프로세스와 거의 동등하다.)나 | |
멀티 프로세스는 cpu 의 코어 갯수 + 1 | |
''' | |
for target in (rcar.FRONTINFRA.update_inputs, | |
rcar.RIGHTINFRA.update_inputs, | |
rcar.RIGHTINFRA.update_valid_status): | |
mp.Process(target=target).start() | |
mp.Process(target=rcar.FRONTINFRA.update_valid_status, | |
args=(rcar.FRONTINFRA.escaping_decide,)).start() | |
time.sleep(2) # 프로세스들을 위해 처음 약간 기다림 | |
try: | |
while True: | |
strace() | |
except KeyboardInterrupt: | |
print('keyboardInterrupt') | |
except ArrivalException: | |
print("도착하였습니다.") | |
except Exception as e: | |
print(e) | |
print("other Exception appeared") | |
finally: | |
GPIO.cleanup() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment