코딩관계론

[SPOT] RMS(Remote Mission Service)가 너무 늦게 끝나요... Thread 문제인가요? 본문

개발/SPOT

[SPOT] RMS(Remote Mission Service)가 너무 늦게 끝나요... Thread 문제인가요?

개발자_티모 2022. 10. 10. 23:56
반응형

결론부터 말하자면 Thread 문제가 아니라 이 액션과 상관없는 네트워크 타임에 의해서 발생하는 문제였다.

 

해결 방법

1. time.time모듈을 이용해 각 구간의 프로그램 실행 시간을 체크함

2. request에서 매번 필요한 keyword를 파싱하는 방법이 아니라 request를 한번만 파싱하고 default dict을 이용하는 방법을 사용함

dev_name = self._parsing_keyword(request, "dev_name")
cmd = self._parsing_keyword(request, "cmd")
min_threshold = self._parsing_keyword(request, "min")
max_threshold = self._parsing_keyword(request, "max")

---------------------------------------------------

keywords = self._parsing_keyword(request)

dev_name = keywords["dev_name"]
cmd = keywords["cmd"]
min_threshold = keywords["min"]
max_threshold = keywords["max"]

3.get_current_mission_name()의 함수가 너무 느렸다. mission_client함수가 grpc를 이용해 scout와 통신하는데 통신이 느린 지역에서 전송량이 큰 정보를 요구하다 보니 더 느렸다.

 위 함수는 Action의 부과적인 기능이다. 단순히 서버에 img결과 값을 올리기 위한 함수임으로 thread를 이용해 background로 처리하도록 변경했다. 

def get_current_mission_name(mission_client):
    """ Gets the mission name from parsing the behavior tree.

    Returns:
        mission name (str): name of the mission currently running
    """
    mission = mission_client.get_mission()

    root_node = nodes_pb2.BosdynRobotState()
    mission.root.impl.Unpack(root_node)
    
    black_board = nodes_pb2.DefineBlackboard()
    root_node.child.impl.Unpack(black_board)
    
    black_board_dict = {}
    
    for var in black_board.blackboard_variables:
        black_board_dict[var.key] = var.value.constant.string_value

    return black_board_dict["MissionScopedMapName"]

 

실수한 내역들

    # Open the bluetooth door once arrived at start
    # Lights will flash at 0.5Hz with brightness of 20% during waiting
    Action Thread():
        with LightsController(self.robot, 0.5, 0.2):
        		do_file_io()

1. 확증편향

with 구문안에 file i/o를 쓰면 안된다는 바보 같은 생각을 함.  프로그램 상태도에 따라 Action Thread가 I/O request에 걸려 wait 상태로 변경 -> 주 쓰레드가 sleep에 들어가면서 LightsController도 thread에 들어간다고 생각함. 잘 생각해보면 틀렸다는 것을 알 수 있다.

process 상태도

하지만 아래의 코드가 위의 상황과 같은데 main 쓰레드가 sleep에 들어가도 hello는 계속 진행을 하고 있다. 너무 이상해서 이상한 생각으로 발전한 것 같다. 

import time
import threading


def hello():
    i = 0

    while i < 15:
        # print("Hello")
        i += 1

    print("종료")

if __name__ == "__main__":
    t = threading.Thread(target=hello)
    t.start()

    time.sleep(10)
    print("main 종료")

2. 감으로 하는 디버깅

SPOT의 LED를 이용해 특정 구간이 끝나면 LED를 하나씩 키도록 설정했다. 그랬더니 3,4번 구간에서 시간이 많이 소모된다는 것을 발견했다. 따라서 해당 코드를 보니 cv2.imencode가 있었다. 엔디비아에 임베디드 보드에서 jpg 이슈가 있다는 것을 보고 png, bmp로 시도했지만 변하는 것이 없었다...

 

 

반응형