I am currently working on driving a bot based on the location of a white ball and I find that giving it negative angular movement moves it to the left rather than the right. Here's a code snippet for what my instruction. Note that for left direction drive_bot has 0.0 linear direction in the x-axis but 0.5 instead of -0.5 for angular motion. The entire project is here but I provide my main code here.

void process_image_callback(const sensor_msgs::Image img)
  const int white_pixel = 255;
  const int image_slice_width = img.step / 3;

  int j;
  bool found = false;

  for (int i = 0; not found and i < img.height; i++)
    for (j = 0; j < img.step; j++)
      // img.data only has one index
      if (img.data[i*img.step +  j     ] == white_pixel and
          img.data[i*img.step + (j + 1)] == white_pixel and
          img.data[i*img.step + (j + 2)] == white_pixel)
          found = true;


void drive_bot(float linear_x, float angular_z)
  // Request a service and pass the velocities to it to drive the robot

  // ROS_INFO_STREAM("Driving bot");
  ball_chaser::DriveToTarget srv;
  srv.request.linear_x = linear_x;
  srv.request.angular_z = angular_z;

  if (not client.call(srv))
    ROS_ERROR("Failed to call service drive to target");


  if (found)
    // determine which third of image ball is
    switch (j / image_slice_width) // split into 3
      case 0: // white ball to the left
        drive_bot(0.0, -0.5);
      case 1: // white ball in front
        drive_bot(0.5, 0.0);
      default: // white ball to the right 
        drive_bot(0.0, 0.5);
    // no white pixel seen so stop the bot
    drive_bot(0.0, 0.0);


I suspect that it may be how the model is put together but I don't see how those values show up in my my_robot.xacro and my_robot.gazebo linked here.

  • $\begingroup$ note: calculate i*img.step before the second for loop ... you are calculating it needlessly numerous times inside the second loop ... you are also checking the same pixel three times in a row, first at j+2, then at j+1 and again at j .... check only one pixel and check the next only if the first is white ... increment j by 3 if you find white/white/unwhite $\endgroup$ – jsotola May 24 '20 at 16:41
  • $\begingroup$ Thanks for the suggestions. I made those changes but kept the signs and it still moves the same way - in the opposite direction. $\endgroup$ – heretoinfinity May 24 '20 at 19:56
  • 1
    $\begingroup$ i did not say that it would give you a different result ... it only made the code faster $\endgroup$ – jsotola May 24 '20 at 20:31
  • $\begingroup$ i do not actually understand what problem you are having ... i see no problem with data being inverted ... all you have to do is multiply the result by -1 $\endgroup$ – jsotola May 24 '20 at 20:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.