0

I currently have a python node that runs a Smach state machine (library linked here: http://wiki.ros.org/smach). I'm using ROS noetic.

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 WAIT_FOR_CALIBRATION_STATE looks like this:

class WaitForCalibrationStart(smach.State):  # Define a state and outcomes
def __init__(self):
    smach.State.__init__(
        self,
        outcomes=["start", "wait"],
    )
    self.toggle_start = False
    rospy.Subscriber(
        "/toggle_start",
        Bool,
        self.callback,
        queue_size=1,
    )

def callback(self, msg):
    self.toggle_start = msg.data

def execute(self, userdata):
    if self.toggle_start:
        rospy.loginfo("Transitioning to STATE1")
        return "start"
    return "wait"

When I run htop, I see that even in the "WAIT_FOR_CALIBRATION" state, when no processes are running or image algorithms are running, there's still a 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 to 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()
  • What version of ROS are you using? Could you be running into this issue? https://github.com/ros/ros_comm/issues/1343 – Nick ODell Oct 13 '22 at 21:56
  • I'm using noetic. I think this thread relates to kinetic? I don't think I understand what this issue is. I'm pretty new to using SMACH. – BlazeRunner738 Oct 13 '22 at 22:09
  • @NickODell that was a roscpp issue. Shouldn’t have effected rospy. – BTables Oct 13 '22 at 23:00
  • @BlazeRunner738 did you ommit any of your code? Seems like you haven't defined [transitions](http://wiki.ros.org/smach/Tutorials/Simple%20State%20Machine#CA-36618d8190e27dad97f4ad2936c1cb44ed1d6e47_45) between states with `smach.StateMachine.add()` – Combinacijus Oct 13 '22 at 23:59
  • @Combinacijus Yeah, there were a few other states and transitions and logic. I can update the comment to show this, but I did try commenting all the logic out and just keeping the states and transitions and it still had high CPU usage. So even with a basic state machine that halts during the WAIT_FOR_.... state. – BlazeRunner738 Oct 14 '22 at 20:13
  • 1
    @BlazeRunner738 code might be stuck in infinite loop without any delay somewhere (just a guess). You could try profile your python code with [cProfile](https://stackoverflow.com/a/582337/5031366) or because it's threaded [this might help](https://stackoverflow.com/questions/653419/how-can-i-profile-a-multithread-program-in-python). This should return how much time is spent in each function (you would want sort on cumtime column) – Combinacijus Oct 14 '22 at 20:55

0 Answers0