Sick Tim publisher and subscriber in one node

asked 2017-03-24 08:32:39 -0500

Dornier gravatar image

Hello!

I'm trying to control Kuka Youbot wheels using the data from Sick Tim 551 sensor. I wrote a node with only one cpp file. The file contains subscriber and publisher, unfortunately i receive a constant error...

"CMakeFiles/wheel_laser.dir/src/wheel_laser.cpp.o: In function `main':
wheel_laser.cpp:(.text+0xb8): undefined reference to `WheelLaser::WheelLaser()'
collect2: ld returned 1 exit status"

The content of the cpp file is:

    #include <termios.h>
    #include <signal.h>
    #include <math.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <ros/ros.h>
    #include <geometry_msgs/Twist.h>
    #include <sensor_msgs/LaserScan.h>

    #define KEYCODE_S 0x73
    #define KEYCODE_W 0x77

    class WheelLaser
    {
    private:
        double translationalSpeed;
        double rotationalSpeed;
        double incremetRate;
        double maxTraveledDistance;
            int experimentNumber;
        bool experimentIsRunning;

        geometry_msgs::Twist baseCommand;
        sensor_msgs::LaserScan lastReceivedLaserScan;

        ros::NodeHandle n;
        ros::Publisher baseCommandPublisher;
            ros::Subscriber baseLaserDataSubscriber;

public:
    WheelLaser();
    virtual ~WheelLaser(){}
    void init();
    void keyboardLoop();
    void startExperiment();
    void stopExperiment();
    void baseLaserDataCallback(const sensor_msgs::LaserScan& scan);

};

int kfd = 0;
struct termios cooked, raw;

void quit(int sig)
{
    tcsetattr(kfd, TCSANOW, &cooked);
    exit(0);
}

int main(int argc, char** argv)
{
    ros::init(argc, argv, "wheel_laser");
    WheelLaser wheelLaser1;
    ros::Rate rate(10);
    ros::AsyncSpinner spinner(4);
    spinner.start();

    signal(SIGINT, quit);
    wheelLaser1.keyboardLoop();

    return 0;
}

 void WheelLaser::init()
 {  baseCommand.linear.x = 0;
    baseCommand.linear.y = 0; 
    baseCommand.angular.z = 0;

    baseCommandPublisher = n.advertise<geometry_msgs::Twist>("cmd_vel", 1);
    baseLaserDataSubscriber = n.subscribe("scan", 50, &WheelLaser::baseLaserDataCallback, this);

    ros::NodeHandle n_private("~");
    n_private.param("translational speed: ", translationalSpeed, 0.1);
    n_private.param("rotational speed: ", rotationalSpeed, 0.1);
    n_private.param("incremet rate: ", incremetRate, 0.1);
    n_private.param("maxtraveled distance: ", maxTraveledDistance, 0.1);

    experimentIsRunning = 0;
    experimentIsRunning = false;
}

void WheelLaser::keyboardLoop()
{
    char c;
    bool dirty = false;

    tcgetattr(kfd, &cooked);
    memcpy(&raw, &cooked, sizeof(struct termios));
    raw.c_lflag &= ~(ICANON | ECHO);

    raw.c_cc[VEOL] = 1;
    raw.c_cc[VEOF] = 2;
    tcsetattr(kfd, TCSANOW, &raw);

    puts("Reading from keyboard");
    puts("---------------------------");
    puts("Use 'W' to start");
    puts("Use 'S' to stop");

    while (true) 
    {
        if (read(kfd, &c, 1) < 0)
        {
            perror("read():");
            exit(-1);
        }
    }
        ROS_INFO("key code %d}\n", c);

        switch (c)
        {
        case KEYCODE_W:
                dirty = true;
                startExperiment();
                break;
        case KEYCODE_S:
            dirty = false;
            stopExperiment();
            break;

        default:
            stopExperiment();
        }

        if (dirty == true)
        {
            baseCommandPublisher.publish(baseCommand);
        }
}

void WheelLaser::startExperiment()
{
        experimentNumber++;
        startTimeStamp = ros::Time::now();
        ROS_INFO_STREAM("Experiment #" << experimentNumber << " Velocities x,y,theta" << baseCommand.linear.x << " " << baseCommand.linear.y << " " << baseCommand.angular.z);
        experimentIsRunning = true;
}

void WheelLaser::stopExperiment()
{
        ROS_INFO("Stop experiment\n");
        baseCommand.linear.x = 0;
        baseCommand.linear.y = 0;
        baseCommand.angular.z = 0;

        if (experimentIsRunning == true)
        {
            ros::Duration timeSinceLastCommand = ros::Time::now() - startTimeStamp;

            ROS_INFO_STREAM("Experiment #" << experimentNumber << ": Traveled Time= " << timeSinceLastCommand);

        }
        experimentIsRunning = false;
}

void WheelLaser::baseLaserDataCallback(const sensor_msgs::LaserScan& scan)
{
        lastReceivedLaserScan = scan;

        if (experimentIsRunning==true)
        {
            if (lastReceivedLaserScan.ranges[100]<1)
            {
                baseCommand.linear.x = -0.1;
            }

            if (lastReceivedLaserScan.ranges[100]>1)
            {
                baseCommand.linear.x = 0.1;
            }
            baseCommandPublisher.publish(baseCommand);
        }

}

CMakeList file consits:

  cmake_minimum_required(VERSION 2.8.3)
    project(WheelLaser)

    ## Find catkin macros and libraries
    ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
    ## is used, also find other catkin packages
    find_package(catkin REQUIRED COMPONENTS

  geometry_msgs
  roscpp
  rospy
  sensor_msgs
  std_msgs
  gencpp)

catkin_package(
#  INCLUDE_DIRS include

#  LIBRARIES WheelLaser
#  CATKIN_DEPENDS gepmetry_msgs nav_msgs roscpp rospy ...
(more)
edit retag flag offensive close merge delete

Comments

You haven't defined the constructor of the class, i.e. replace ; with {}.

nlamprian gravatar image nlamprian  ( 2017-03-24 08:51:47 -0500 )edit