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

Motor controller works only when I print using loginfo in cmd_vel callback

asked 2019-04-25 07:32:02 -0500

robotjohan gravatar image

I am using a Roboclaw Motor Controller which I control using software I have taken from Github and modified. I am publishing Twist messages using teleop_twist_joy. This works fine when I have the line rospy.loginfo("") in my cmd_vel callback but when I remove the loginfo I get latencies and generally weird behavior. For example the robot will stand still for a while before starting to move and it will also keep moving after I release the joypad activation button.

I have a callback on cmd_vel which looks like this:

        def cmd_vel_callback(self, twist):                                                                                                                                                                  
            if not self.paused:                                                                                                                                                                         
                    self.last_set_speed_time = rospy.get_rostime()                                                                                                                                      

                    linear_x = twist.linear.x                                                                                                                                                           
                    if linear_x >  self.MAX_SPEED: linear_x =  self.MAX_SPEED                                                                                                                           
                    if linear_x < -self.MAX_SPEED: linear_x = -self.MAX_SPEED                                                                                                                           

                    Vr = linear_x + twist.angular.z*self.BASE_WIDTH/2.0 # m/s                                                                                                                           
                    Vl = linear_x - twist.angular.z*self.BASE_WIDTH/2.0                                                                                                                                 

                    Vr_ticks = int(Vr * self.TICKS_PER_METER) # ticks/s                                                                                                                                 
                    Vl_ticks = int(Vl * self.TICKS_PER_METER)                                                                                                                                           

                    rospy.loginfo("")                                                                                                                                                                  

                    self.roboclaw.SetSpeed(Vl_ticks,Vr_ticks)

Notice the line rospy.loginfo(""), when I comment this things stop working. To make things work I can either uncomment that line again or have a second callback like this:

        def cmd_vel_log_callback(self, twist):                                                                                                                                                              
            rospy.loginfo("")

The code for subscribing that I use is:

            rospy.Subscriber('cmd_vel', Twist, self.cmd_vel_callback)                                                                                                                                   
            rospy.Subscriber('cmd_vel', Twist, self.cmd_vel_log_callback)

This is of course unsatisfactory and I would like to understand how I can get things working without the extra rospy.loginfo("").

I am using melodic on Ubuntu 18.04.2 LTS.

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
2

answered 2019-04-25 08:03:41 -0500

gvdhoorn gravatar image

updated 2019-04-25 08:04:53 -0500

It is very likely that self.roboclaw.SetSpeed(Vl_ticks,Vr_ticks) just cannot be called as fast as it would be if you comment the rospy.loginfo("") line. By having that line there, as a side-effect, you delay the call to SetSpeed(..) by some milliseconds giving something time to actually do some work.

re: motion after letting go of the button: that sounds like your node processing a backlog of incoming messages. You'll want to configure your subscriber such that it doesn't maintain any queue, so only the most recent message is processed.

edit flag offensive delete link more

Comments

That seems very reasonable.

Do you have any suggestion on a good way of limiting the rate? I guess I could just scrap messages if they arrive to soon. This makes me worry that I will miss important messages, say a stop message, if it arrives untimely. I could then keep a log of the most recent message and make sure it is sent when possible. It seems my issue then is that I would like to know if there is a ROS way of doing this, or if I should just make it work somehow (maybe that is the ROS way?).

I'll also look into whether I keep a queue!

Thank you for your help!

robotjohan gravatar image robotjohan  ( 2019-04-26 02:36:47 -0500 )edit

Do you have any suggestion on a good way of limiting the rate?

While I'm always a fan of making ROS nodes completely event-based (ie: do work when msgs come in), in this case a periodic while with a ros::Rate and a copy of "the latest" message (as a member variable fi) might be an OK approach.

To make all of this less guesswork, you might want to see whether you can find some information on SetSpeed(..) and the rest of the roboclaw library you're using. Perhaps there are some specs on the runtime behaviour that explain all of this.

Right now we're just guessing, which makes suggesting an architecture/design rather difficult.

gvdhoorn gravatar image gvdhoorn  ( 2019-04-26 04:26:15 -0500 )edit

I didn't manage to get any information on how often I can call SetSpeed. For now I went ahead and implemented a variable which stores the values from the last message and send an update to the motor controller with a frequency of 100 Hz which seems to work fine.

I also changed the queue size to 1 which did the trick.

Again, thank you for your help!

robotjohan gravatar image robotjohan  ( 2019-04-26 07:00:58 -0500 )edit

Question Tools

Stats

Asked: 2019-04-25 07:32:02 -0500

Seen: 168 times

Last updated: Apr 25 '19