CPU usage for state machine node runs at 100%

asked 2022-10-13 16:16:01 -0500

Blazerunner738 gravatar image

updated 2022-10-18 15:16:10 -0500

I currently have a python node that runs a Smach state machine.. The state machine starts in an IDLE state, which looks like this:

class Idle(smach.State):
    def __init__(self):
        smach.State.__init__(
            self,
            outcomes=["state_reset_complete"],
            input_keys=[
                "img_diff",
                "img1",
                "img3",
            ],
            output_keys=[
                "img_diff",
                "img1",
                "img2",
            ],
        )

    def execute(self, userdata):
        rospy.loginfo("Idle")
        userdata.img_diff = None
        userdata.img1 = None
        userdata.img2 = None
        rospy.loginfo("Transitioning to WAIT_FOR_CALIBRATION_START")
        return "state_reset_complete"

The init_sm() is as follows:

def init_sm(): # create SMACH state machine sm = smach.StateMachine(outcomes=["finished"]) sm.set_initial_state(["IDLE"])

sm.userdata.full_mask_img = None
sm.userdata.current_diff_mask = None
sm.userdata.scan_only_mask_img = None

with sm:  # This opens sm container for adding states:
    smach.StateMachine.add(
        "IDLE",
        Idle(),
        transitions={"state_reset_complete": "WAIT_FOR_CALIBRATION_START"},
    )

    smach.StateMachine.add(
        "WAIT_FOR_CALIBRATION_START",
        WaitForCalibrationStart(),
        transitions={
            "start_calibration": "STATE1",
            "wait": "WAIT_FOR_CALIBRATION_START",
        },
    )

    smach.StateMachine.add(
        "STATE1",
        State1(),
        transitions={
            "complete": "STATE2",
            "active": "STATE1",
        },
    )

    smach.StateMachine.add(
        "STATE2",
        State2(),
        transitions={"complete": "IDLE"},
    )

return sm

When I run htop command, I see that even in the "IDLE" state, when no processes are running or image algorithms are running, there's still 100% CPU usage. Does anyone know why this could be happening? Is there a good way to fix this?

Also, not sure if this is related. But Ctrl+C doesn't cleanly exit the node sometimes. Especially when not in the IDLE state. Any ideas for fixing this?

This is what my main looks like:

if __name__ == "__main__":
    rospy.init_node("node")

    sm = init_sm()  # Create state machine
    # Create a thread to execute the smach container
    smach_thread = threading.Thread(target=sm.execute)
    smach_thread.start()

    # Wait for ctrl-c
    rospy.spin()

    # Request the container to preempt
    sm.request_preempt()

    # Block until everything is preempted
    smach_thread.join()

The CPU is still overloaded if I change main to:

if __name__ == "__main__":
    rospy.init_node("node")

    sm = init_sm()  # Create state machine
    sm.execute()

    # Wait for ctrl-c
    rospy.spin()
edit retag flag offensive close merge delete

Comments

Can you post the code of init_sm? Or rather, what state does Idle transition to when it's outcome is state_reset_complete. I agree it should not use so much CPU, but if the state transitions back to itself then there's an infinite loop.

Loy gravatar image Loy  ( 2022-10-17 00:35:31 -0500 )edit

Added the init_sm(). Idle transitions to Wait for calibration start where it waits until a button is pressed. The idea is to have the be an infinite state machine and keep watching for a button press.

Blazerunner738 gravatar image Blazerunner738  ( 2022-10-18 15:17:32 -0500 )edit

Did you try to loop? Something along the line of

rate = rospy.Rate(10)
while not rospy.is_shutdown():
    sm.execute()
    rate.sleep()
Vic gravatar image Vic  ( 2022-10-20 03:07:21 -0500 )edit