0
$\begingroup$

Rosanswers logo

hello everyone
I wrote my class structure in a header file (stage_listener.h):

#ifndef sl_H
#define sl_H

#include "ros/ros.h"
#include "nav_msgs/Odometry.h"
#include "geometry_msgs/Pose.h"
#include "geometry_msgs/Point.h"
#include "stdio.h"
#include "sensor_msgs/LaserScan.h"
#include "list"
#include "vector"
#include "scan_node.h"
#include "odom_node.h"
#include "coord.h"

class stage_listener{
public:
    stage_listener(){};
    int numOdom();
    int numScan();
    
private:
    std::list odom_list;
    std::list scan_list;
    std::list corners_list;
    
    std::list polar2cart(std::vector, float, float, float, float);
    void addOdomNode (const nav_msgs::Odometry);
    void addScanNode (const sensor_msgs::LaserScan);
    void extractCorners(std::vector, float, float, float, float);
    int distance (float, float, float, float, float);
    void nodes2text(std::vector, std::vector);

};  


#endif

Then I wrote its associated .cpp file (stage_listener.cpp):

#include "ros/ros.h"
#include "nav_msgs/Odometry.h"
#include "geometry_msgs/Pose.h"
#include "geometry_msgs/Point.h"
#include "stdio.h"
#include "sensor_msgs/LaserScan.h"
#include "stage_listener.h"
#include "odom_node.h"
#include "scan_node.h"
#include "tf/transform_listener.h"
#include "list"
#include "vector"
#include "coord.h"
#include "math.h"
#include "stdlib.h"
#include "iterator"
#include "string"


stage_listener::stage_listener(){}

int stage_listener::numOdom(){
    return (int)(odom_list.size());
}

int stage_listener::numScan(){
    return (int)(scan_list.size());
}

void stage_listener::addOdomNode (const nav_msgs::Odometry mes){
    geometry_msgs::Pose robot_pose = mes.pose.pose;
    geometry_msgs::Point robot_point = robot_pose.position;

    odom_node *on = new odom_node();
    (*on).xCoord = robot_point.x;
    (*on).yCoord = robot_point.y;
    (*on).frame_id = mes.header.frame_id;
    
    double orientation = tf::getYaw(robot_pose.orientation);
    (*on).angle = (float)orientation;
    
    odom_list.push_back(*on);
}

std::list stage_listener::polar2cart(std::vector v, float a_min, float a_inc, float range_min, float range_max){
    std::list lc;
    for(int i=0; i= range_min && v[i] points, float d_max, std::list dest){
    if(points.size() == 1){
        coord *corner = new coord();
        (*corner).x = points.front().x;
        (*corner).y = points.front().y;
        dest.push_back(*corner);
    }
    
    else if(points.size() == 2){
        coord *corner_a = new coord();
        coord *corner_b = new coord();
        
        (*corner_a).x = points.front().x;
        (*corner_a).y = points.front().y;
        
        
        (*corner_b).x = points.back().x;
        (*corner_b).y = points.back().y;
        
        dest.push_back(*corner_a);
        dest.push_back(*corner_b);
    }
    
    else{
        std::list::iterator i = points.end();
        float x1 = points.front().x;
        float y1 = points.front().y;
        float x2 = (*i).x;
        float y2 = (*i).y;
        
        float a = y1-y2;
        float b = x2-x1;
        float c = y1*(x1-x2) + x1*(y2-y1);
        
        int max = 0;
        int ref = 0;
        int count = points.size()-2;
        i--;
        
        while(i!=points.begin()){
            coord temp = (*i);
            int d = distance(a,b,c,temp.x,temp.y);
            if(d>d_max && d>max){
                max = d;
                ref = count;
            }
            
            count--;
            i--;    
        }
        
        if(max == 0){
            coord *corner_a = new coord();
            coord *corner_b = new coord();
            
            (*corner_a).x = points.front().x;
            (*corner_a).y = points.front().y;

            (*corner_b).x = points.back().x;
            (*corner_b).y = points.back().y;
            
            dest.push_back(*corner_a);
            dest.push_back(*corner_b);
            points.clear();
        }
        
        else{
            std::list::iterator first = points.begin();
            std::list::iterator med = points.begin();
            std::list::iterator end = points.end();
            
            std::advance(med,ref+1);
            
            std::list left(first, med);
            std::list right(med, end);
            right.push_back(points.back());
            
            extractCorners(left, d_max, dest);
            extractCorners(right, d_max, dest);
            
        }
    }

}

void stage_listener::nodes2text(std::vector odom, std::vector scan){
    FILE *fid = fopen("nodes_text.txt","a");
    std::vector::iterator odom_it = odom.begin();
    std::vector::iterator scan_it = scan.begin();
    
    float prev_x = 0;
    float prev_y = 0;
    float prev_angle = 0;
    std::string prev_id;
    
    while(odom_it!= odom.end()){
        std::stringstream ss_vertex, ss_edge;
        std::list::iterator corner_it = (*scan_it).corners_list.begin();
        
        ss_vertex  "  \n";
            std::string corner_str = ss_corner.str();
            
            fwrite(corner_str.c_str(),sizeof(char),sizeof(char)*sizeof(corner_str),fid);
        }
        
        if(odom_it!=odom.begin()){
            float dx = (*odom_it).xCoord - prev_x;
            float dy = (*odom_it).yCoord - prev_y;
            float dth = (*odom_it).angle - prev_angle;
            
            ss_edge   " 

In a separate file, I wrote a test main() function(stage_main.cpp):

#include "ros/ros.h"
#include "stage_listener.h"
#include "nav_msgs/Odometry.h"
#include "geometry_msgs/Pose.h"
#include "geometry_msgs/Point.h"
#include "stdio.h"
#include "sensor_msgs/LaserScan.h"
#include "odom_node.h"
#include "scan_node.h"
#include "tf/transform_listener.h"
#include "list"
#include "vector"
#include "coord.h"
#include "math.h"
#include "stdlib.h"
#include "iterator"
#include "string"

int main(int argc, char **argv){
    stage_listener *sl = new stage_listener();
    char buffer [1024];
    while(1){
        int i = fscanf(stdin,"%s",buffer);
        
        if(strcmp("exit",buffer) == 0)
            exit(0);
            
        else if(strcmp("num_nodes",buffer) == 0){
            //ROS_INFO("Odometry nodes: %i\nScan nodes: %i",sl.numOdom(),sl.numScan());
            int b = (*sl).numOdom();
        }
        
        else{}
    }

}

Regarding instruction

int b = (*sl).numOdom();

I get this error:

Linking CXX executable ../bin/stage_main
CMakeFiles/stage_main.dir/src/stage_main.o: In function `main':
/home/ubisum/fuerte_workspace/beginner/src/stage_main.cpp:30: undefined reference to `stage_listener::numOdom()'

This is the content of my CMakeLists file:

cmake_minimum_required(VERSION 2.4.6) include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake) # Set the build type. Options are: # Coverage : w/ debug symbols, w/o optimization, w/ code-coverage # Debug : w/ debug symbols, w/o optimization # Release : w/o debug symbols, w/ optimization # RelWithDebInfo : w/ debug symbols, w/ optimization # MinSizeRel : w/o debug symbols, w/ optimization, stripped binaries #set(ROS_BUILD_TYPE RelWithDebInfo) rosbuild_init() #set the default path for built executables to the "bin" directory set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) #set the default path for built libraries to the "lib" directory set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib) #uncomment if you have defined messages #rosbuild_genmsg() #uncomment if you have defined services #rosbuild_gensrv() #common commands for building c++ executables and libraries #rosbuild_add_library(${PROJECT_NAME} src/example.cpp) #target_link_libraries(${PROJECT_NAME} another_library) #rosbuild_add_boost_directories() #rosbuild_link_boost(${PROJECT_NAME} thread) #rosbuild_add_executable(example examples/example.cpp) #target_link_libraries(example ${PROJECT_NAME}) rosbuild_add_executable(listener src/listener.cpp) rosbuild_add_executable(stage_main src/stage_main.cpp)

I checked: .h file was correctly included into one containing main function, invoked functions are public, their implementation is present in .cpp file. I tried even to create object sl without use of new but nothing changed. Have you got any clue?

Thanks for help


Originally posted by ubisum on ROS Answers with karma: 23 on 2012-12-05

Post score: 0

$\endgroup$

2 Answers 2

0
$\begingroup$

Rosanswers logo

Your CMake states that you will build two independent nodes.

You want the listener.cpp to be build into state_main, not into a separate listener executable, so add src/stage_listener.cpp to the stage_main line and remove the listener entry.


Originally posted by dornhege with karma: 31395 on 2012-12-05

This answer was ACCEPTED on the original site

Post score: 1

$\endgroup$
0
$\begingroup$

Rosanswers logo

That is a linker error. You compiled stage_main without a copy of listener.cpp.

Try this in your CMakeLists.txt:

rosbuild_add_executable(stage_main src/stage_main.cpp src/listener.cpp)

A better solution would involve creating a listener shared library which stage_main could reference.


Originally posted by joq with karma: 25443 on 2012-12-05

This answer was NOT ACCEPTED on the original site

Post score: 1

$\endgroup$

Your Answer

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