ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Your question title made me think you wanted to publish multiple topics at various rates, in which case timers (roscpp, rospy) are probably better than a while loop. Since you specified using the loop, we'll move on with that.

Are you trying to publish one topic (/control) at one specific rate (30 Hz)? If so, you need to add something to make the loop take the specified time, which won't be exact--especially with waitKey() in there. As is, your code specifies a timer that triggers control() at your desired rate, but you also call control() from inside the while loop. To use the while loop for timing, remove the rospy.Timer() and use rospy.Rate(). From the tutorial:

rate = rospy.Rate(10) # 10hz
while not rospy.is_shutdown():
    hello_str = "hello world %s" % rospy.get_time()
    rospy.loginfo(hello_str)
    pub.publish(hello_str)
    rate.sleep()

Since your loop is in run(), the sleep should go at the end of that loop:

def run(self):
    global error_v, error_w, array
    rate = rospy.Rate(30)
    while not rospy.is_shutdown():
        if self._current_image is not None:
            try:
                scene = self._bridge.imgmsg_to_cv2(self._current_image, "bgr8")
                self.error_v = 2
                self.error_w = 1
                # hello_str = [error_v, error_w]
                # array = Float32MultiArray(data=hello_str)
                self.control()

                cv2.imshow("image", scene)
                key = cv2.waitKey(1)
            except CvBridgeError as e:
                print(e)
        rate.sleep()

Again, this will be best effort timing--not exact. The sleep will try to vary its length to take up the rest of the desired loop period.