0
$\begingroup$

Rosanswers logo

It is a programme which aims to make a robot follow a ball. I used 18.04 Unbuntu. When I try to 'catkin_make', the error happened in ' vel_pub = nh.advertise("/cmd_vel", 30); ' (line 133). I dont know why and I am not familiar with ROS and C++.

#include <ros/ros.h>
#include <cv_bridge/cv_bridge.h>

#include <sensor_msgs/image_encodings.h>

#include <opencv2/imgproc/imgproc.hpp>

#include <opencv2/highgui/highgui.hpp>

#include <geometry_msgs/Twist.h>


using namespace cv;
using namespace std;

static int iLowH = 10;
static int iHighH = 40;

static int iLowS = 90;
static int iHighS = 255;

static int iLowV = 1;
static int iHighV = 255;

geometry_msgs::Twist vel_cmd;   //speed message packet

ros::Publisher vel_pub;      //Velocity Post Object

void Cam_RGB_Callback(const sensor_msgs::ImageConstPtr& msg)
{
    cv_bridge::CvImagePtr cv_ptr;
    try
    {
    cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
}
catch (cv_bridge::Exception& e)
{
    ROS_ERROR("cv_bridge exception: %s", e.what());
    return;
}

Mat imgOriginal = cv_ptr->image;

//Convert RGB image to HSV
Mat imgHSV;
vector<Mat> hsvSplit;
cvtColor(imgOriginal, imgHSV, COLOR_BGR2HSV);

//Do histogram equalization in HSV space
split(imgHSV, hsvSplit);
equalizeHist(hsvSplit[2],hsvSplit[2]);
merge(hsvSplit,imgHSV);
Mat imgThresholded;

//Binarize the image using the threshold ranges of Hue, Saturation and Value above
inRange(imgHSV, Scalar(iLowH, iLowS, iLowV), Scalar(iHighH, iHighS, iHighV), imgThresholded);

//On operation (remove some noise)
Mat element = getStructuringElement(MORPH_RECT, Size(5, 5));
morphologyEx(imgThresholded, imgThresholded, MORPH_OPEN, element);

//Close operation (connect some connected domains)
morphologyEx(imgThresholded, imgThresholded, MORPH_CLOSE, element);

//Traverse the binarized image data
int nTargetX = 0;
int nTargetY = 0;
int nPixCount = 0;
int nImgWidth = imgThresholded.cols;
int nImgHeight = imgThresholded.rows;
int nImgChannels = imgThresholded.channels();
printf("horizontal width= %d   vertical height= %d\n",nImgWidth,nImgHeight);
for (int y = 0; y < nImgHeight; y++)
{
    for(int x = 0; x < nImgWidth; x++)
    {
        if(imgThresholded.data[y*nImgWidth + x] == 255)
        {
            nTargetX += x;
            nTargetY += y;
            nPixCount ++;
        }
    }
}
if(nPixCount > 0)
{
    nTargetX /= nPixCount;
    nTargetY /= nPixCount;
    printf("Color centroid coordinates( %d , %d )  point= %d\n",nTargetX,nTargetY,nPixCount);
    //draw coordinates
    Point line_begin = Point(nTargetX-10,nTargetY);
    Point line_end = Point(nTargetX+10,nTargetY);
    line(imgOriginal,line_begin,line_end,Scalar(255,0,0),3);
    line_begin.x = nTargetX; line_begin.y = nTargetY-10;
    line_end.x = nTargetX; line_end.y = nTargetY+10;
    line(imgOriginal,line_begin,line_end,Scalar(255,0,0),3);
    //Calculate robot motion speed
    float fVelFoward = (nImgHeight/2-nTargetY)*0.002;     //Difference * Proportion
    float fVelTurn = (nImgWidth/2-nTargetX)*0.003;        //Difference * Proportion
    vel_cmd.linear.x = fVelFoward;
    vel_cmd.linear.y = 0;
    vel_cmd.linear.z = 0;
    vel_cmd.angular.x = 0;
    vel_cmd.angular.y = 0;
    vel_cmd.angular.z = fVelTurn;
}
else
{
    printf("target color disappears...\n");
    vel_cmd.linear.x = 0;
    vel_cmd.linear.y = 0;
    vel_cmd.linear.z = 0;
    vel_cmd.angular.x = 0;
    vel_cmd.angular.y = 0;
    vel_cmd.angular.z = 0;
}

vel_pub.publish(vel_cmd);
printf("Robot movement speed( linear= %.2f , angular= %.2f )\n",vel_cmd.linear.x,vel_cmd.angular.z);

//Display processing results
imshow("RGB", imgOriginal);
imshow("Result", imgThresholded);
cv::waitKey(1);
}

int main(int argc, char **argv)

{
    ros::init(argc, argv, "cv_image_node");
  
ros::NodeHandle nh;
ros::Subscriber rgb_sub = nh.subscribe("/nao_robot/camera_bottom/image_raw", 1 , Cam_RGB_Callback);

vel_pub = nh.advertise("/cmd_vel", 30);

ros::Rate loop_rate(30);

//The window for generating image display and parameter adjustment is empty
namedWindow("Threshold", CV_WINDOW_AUTOSIZE);

cvCreateTrackbar("LowH", "Threshold", &iLowH, 179); //Hue (0 - 179)
cvCreateTrackbar("HighH", "Threshold", &iHighH, 179);

cvCreateTrackbar("LowS", "Threshold", &iLowS, 255); //Saturation (0 - 255)
cvCreateTrackbar("HighS", "Threshold", &iHighS, 255);

    cvCreateTrackbar("LowV", "Threshold", &iLowV, 255); //Value (0 - 255)
    cvCreateTrackbar("HighV", "Threshold", &iHighV, 255);

    namedWindow("RGB");
    namedWindow("Result");
    while( ros::ok())
    {
        ros::spinOnce();
        loop_rate.sleep();
    }
}

Originally posted by doukione on ROS Answers with karma: 3 on 2022-03-15

Post score: 0

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

Please see the roscpp overview on Publishers and Subscribers for example usage and API links. To me it looks like you are missing the required template parameter for the ros::NodeHandle::advertise method. You likely need to change the call to something like

vel_pub = nh.advertise<geometry_msgs::Twist>("/cmd_vel", 30);

Originally posted by jarvisschultz with karma: 9031 on 2022-03-15

This answer was ACCEPTED on the original site

Post score: 0


Original comments

Comment by doukione on 2022-03-15:
It worked! Thank you very much!!!

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.