ROS Python 타이머가 많이 끊겨요.

5771 단어 ROSubuntu18.04

의 목적


다음의 목적을 위해 ROS Python의 timer call back을 대량으로 실행하고 PC의 부하를 조사해 봤다.
· CPU에 대해 자세히 알고 싶습니다
・thread에 대해 자세히 알고 싶어요.

실험 내용


프로그램은 다음과 같다. callback 설정 함수의 순환 횟수를 늘리고 PC의 부하를 조사한다.
timer_callback_many.py
import rospy

def callback(msg):
  print("callback")

rospy.init_node('timer_callback')

for i in range(20000):
  rospy.Timer(rospy.Duration(1), callback)

r = rospy.Rate(3) 
while not rospy.is_shutdown():
  print("loop")
  r.sleep()

timer callback의 개수를 10000개로 설정했을 때top 명령에 나타난 변화는 다음과 같다. 파이톤3의 CPU 사용률이 크게 변했기 때문에 이 값을 주목하기로 했다.
실행 전

실행 후

결실


인터럽트 개수를 10000~2000초로 늘리고 각각의 CPU 사용률을 10초마다 기록한다.
마지막 20000시표 계산 소프트웨어가 늘어나 기록이 사라져 결과의 개요만 썼다.
CPU 사용률이 1000~15000대까지 올랐다.
16000~19000 정도의 CPU 사용률은 130%에서 변경되지 않음
20000 프로그램이 오류를 토해냈다(전자표 소프트웨어도 떨어졌다)

총결산


16000 정도 처리 속도가 늦은 것 같아요.
20000개 정도가 자기 pc의thread의 극한수?

ROS 타이머 중단 내부


https://github.com/ros/ros_comm/blob/noetic-devel/clients/rospy/src/rospy/timer.py
의 190번째 행이 정의됩니다.
내부 계승threading.Thread.
class Timer(threading.Thread):
    """
    Convenience class for calling a callback at a specified rate
    """

    def __init__(self, period, callback, oneshot=False, reset=False):
        """
        Constructor.
        @param period: desired period between callbacks
        @type  period: rospy.Duration
        @param callback: callback to be called
        @type  callback: function taking rospy.TimerEvent
        @param oneshot: if True, fire only once, otherwise fire continuously until shutdown is called [default: False]
        @type  oneshot: bool
        @param reset: if True, timer is reset when rostime moved backward. [default: False]
        @type  reset: bool
        """
        super(Timer, self).__init__()
        self._period   = period
        self._callback = callback
        self._oneshot  = oneshot
        self._reset = reset
        self._shutdown = False
        self.daemon = True
        self.start()

    def shutdown(self):
        """
        Stop firing callbacks.
        """
        self._shutdown = True

    def run(self):
        r = Rate(1.0 / self._period.to_sec(), reset=self._reset)
        current_expected = rospy.rostime.get_rostime() + self._period
        last_expected, last_real, last_duration = None, None, None
        while not rospy.core.is_shutdown() and not self._shutdown:
            try:
                r.sleep()
            except rospy.exceptions.ROSInterruptException as e:
                if rospy.core.is_shutdown():
                    break
                raise
            if self._shutdown:
                break
            current_real = rospy.rostime.get_rostime()
            start = time.time()
            self._callback(TimerEvent(last_expected, last_real, current_expected, current_real, last_duration))
            if self._oneshot:
                break
            last_duration = time.time() - start
            last_expected, last_real = current_expected, current_real
            current_expected += self._period
Threading.Thread 클래스 설명: https://docs.python.org/ja/3/library/threading.html
그것의 내부: https://docs.python.org/ja/3/library/_thread.html#module-_thread

컨디션


또 이번에 사용한 환경은 다음과 같다.
https://qiita.com/hoshianaaa/items/632e0eb9ddacb8245e66

좋은 웹페이지 즐겨찾기