Robotics StackExchange | Archived questions

Why is my GTK+ version clashes when i try to run an executable?

Hello everyone,

I'm trying to run an executable in my code but suddenly this error pop up.

(view:26020): Gtk-ERROR **: GTK+ 2.x symbols detected. Using GTK+ 2.x and GTK+ 3 in the same process is not supported Trace/breakpoint trap (core dumped)

I tried to include the gtk in my CMakeLists and my cpp file (for the executable) but still didn't work.

Here's my CMakeLists:

    cmake_minimum_required(VERSION 2.8.3)
project(a3_help)

## 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
  cv_bridge
  image_transport
  message_generation
  roscpp
  sensor_msgs
  std_msgs
  OpenCV
)

add_definitions( -DANALYSIS=ON )
##ADD_DEFINITIONS(${GTK_CFLAGS_OTHER})

## System dependencies are found with CMake's conventions
find_package(Boost REQUIRED COMPONENTS system signals)
##find_package(PkgConfig REQUIRED)
##pkg_check_modules(GTK REQUIRED gtk+-3.0)
##find_package(GTK2 2.6 REQUIRED gtk)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated -Wdeprecated-declarations")
set(CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS}")

message ( STATUS " CMake C++ FLAGS ${CMAKE_CXX_FLAGS}")

find_package(OpenCV)
find_package(Eigen3 REQUIRED)

## Uncomment this if the package has a setup.py. This macro ensures
## modules and global scripts declared therein get installed
## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
# catkin_python_setup()

################################################
## Declare ROS messages, services and actions ##
################################################

## To declare and build messages, services or actions from within this
## package, follow these steps:
## * Let MSG_DEP_SET be the set of packages whose message types you use in
##   your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
## * In the file package.xml:
##   * add a build_depend tag for "message_generation"
##   * add a build_depend and a run_depend tag for each package in MSG_DEP_SET
##   * If MSG_DEP_SET isn't empty the following dependency has been pulled in
##     but can be declared for certainty nonetheless:
##     * add a run_depend tag for "message_runtime"
## * In this file (CMakeLists.txt):
##   * add "message_generation" and every package in MSG_DEP_SET to
##     find_package(catkin REQUIRED COMPONENTS ...)
##   * add "message_runtime" and every package in MSG_DEP_SET to
##     catkin_package(CATKIN_DEPENDS ...)
##   * uncomment the add_*_files sections below as needed
##     and list every .msg/.srv/.action file to be processed
##   * uncomment the generate_messages entry below
##   * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)

## Generate messages in the 'msg' folder
# add_message_files(
#   FILES
#   Message1.msg
#   Message2.msg
# )

## Generate services in the 'srv' folder
add_service_files(
   FILES
   RequestGoal.srv
)

## Generate actions in the 'action' folder
# add_action_files(
#   FILES
#   Action1.action
#   Action2.action
# )

## Generate added messages and services with any dependencies listed here
generate_messages(
   DEPENDENCIES
   sensor_msgs#   std_msgs
)


###################################
## catkin specific configuration ##
###################################
## The catkin_package macro generates cmake config files for your package
## Declare things to be passed to dependent projects
## INCLUDE_DIRS: uncomment this if you package contains header files
## LIBRARIES: libraries you create in this project that dependent projects also need
## CATKIN_DEPENDS: catkin_packages dependent projects also need
## DEPENDS: system dependencies of this project that dependent projects also need
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES a3_help
#  CATKIN_DEPENDS roscpp sensor_msgs std_msgs
#  DEPENDS system_lib
)

###########
## Build ##
###########

## Specify additional locations of header files
## Your package locations should be listed before other locations
# include_directories(include)

include_directories(
  include
  ${catkin_INCLUDE_DIRS}
  ${EIGEN3_INCLUDE_DIR}
  ${OpenCV_INCLUDE_DIRS}
  ##${GTK_INCLUDE_DIRS}
)

## Declare a C++ library
# add_library(a3_help
#   src/${PROJECT_NAME}/a3_help.cpp
# )

## Add cmake target dependencies of the library
## as an example, code may need to be generated before libraries
## either from message generation or dynamic reconfigure
# add_dependencies(a3_help ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

## Declare a C++ executable
#add_executable(gazebo_retrieve src/gazebo_retrieve.cpp)
add_executable(map_to_image_node src/map_to_image_node.cpp)
add_executable(sample src/sample.cpp)
add_executable(TBK src/TBK.cpp)


## Add cmake target dependencies of the executable
## same as for the library above
# add_dependencies(a3_help_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

## Specify libraries to link a library or executable target against
#target_link_libraries(gazebo_retrieve ${catkin_LIBRARIES})
target_link_libraries(map_to_image_node ${catkin_LIBRARIES})
target_link_libraries(sample ${catkin_LIBRARIES} ) ##${GTK_LIBRARIES}
target_link_libraries(TBK ${catkin_LIBRARIES})

#target_link_libraries(image_publisher ${catkin_LIBRARIES} ${OpenCV_LIBRARIES})

#############
## Testing ##
#############

## Add gtest based cpp test target and link libraries
#catkin_add_gtest(${PROJECT_NAME}-test test/utest.cpp src/raytracer.cpp)
catkin_add_gtest(${PROJECT_NAME}-test test/utest.cpp )
if(TARGET ${PROJECT_NAME}-test)
   target_link_libraries(${PROJECT_NAME}-test ${catkin_LIBRARIES})
endif()

## Add folders to be run by python nosetests
# catkin_add_nosetests(test)

Here's my cpp file (sample.cpp):

#include "ros/ros.h"
#include "std_msgs/String.h"
#include "gazebo_msgs/ModelStates.h"
#include "tf/transform_datatypes.h"

#include "sensor_msgs/LaserScan.h"
#include "sensor_msgs/image_encodings.h"
#include "nav_msgs/Odometry.h"
#include <opencv2/imgproc/imgproc.hpp>
#include <image_transport/image_transport.h>
#include <opencv2/highgui/highgui.hpp>
#include <cv_bridge/cv_bridge.h>

#include "a3_help/RequestGoal.h"

#include <sstream>
#include <iostream>
#include <string>

#include <thread>
#include <chrono>
#include <deque>
#include <mutex>
#include <random>

namespace enc = sensor_msgs::image_encodings;

/**
 * This node shows some connections and publishing images
 */


class GazeboRetrieve{

    ros::NodeHandle nh_;
    image_transport::ImageTransport it_;
    image_transport::Publisher image_pub_;
    ros::Subscriber sub1_;
    ros::Subscriber sub2_;
    image_transport::Subscriber sub3_;
    cv_bridge::CvImagePtr cvPtr_;
    ros::ServiceServer service_;

    int count_;//! A counter to allow executing items on N iterations
    double resolution_;//! size of OgMap in pixels

    struct DataBuffer
    {
        std::deque<geometry_msgs::Pose> poseDeq;
        std::deque<ros::Time> timeStampDeq;
        std::mutex buffer_mutex_;
    };
    DataBuffer buffer;//! And now we have our container

    struct ImageDataBuffer
    {
        std::deque<cv::Mat> imageDeq;
        std::deque<ros::Time> timeStampDeq;
        std::mutex buffer_mutex_;
    };
    ImageDataBuffer imageBuffer;//! And now we have our container


public:
    GazeboRetrieve(ros::NodeHandle nh)
    : nh_(nh), it_(nh)
    {
        sub1_ = nh_.subscribe("odom", 1000, &GazeboRetrieve::odomCallback,this);
        sub2_ = nh_.subscribe("scan", 10, &GazeboRetrieve::laserCallback,this);
        image_transport::ImageTransport it(nh);
        sub3_ = it.subscribe("map_image/full", 1, &GazeboRetrieve::imageCallback,this);

        //Publishing an image ... just to show how
        image_pub_ = it_.advertise("test/image", 1);

        //Allowing an incoming service
        service_ = nh_.advertiseService("request_goal", &GazeboRetrieve::requestGoal,this);

        //Below is how to get parameters from command line, on command line they need to be _param:=value
        ros::NodeHandle pn("~");
        double mapSize;
        double resolution;
        pn.param<double>("map_size", mapSize, 20.0);
        pn.param<double>("resolution", resolution_, 0.1);

        count_ =0;
        cv::namedWindow("view",CV_WINDOW_NORMAL);
        cv::startWindowThread();
        cv::waitKey(5);

    }

    ~GazeboRetrieve()
    {
        cv::destroyWindow("view");
    }


    bool requestGoal(a3_help::RequestGoal::Request  &req,
             a3_help::RequestGoal::Response &res)
    {
      ROS_INFO("request: x=%ld, y=%ld", (long int)req.x, (long int)req.y);
      res.ack = true;
      ROS_INFO("sending back response: [%d]", res.ack);
      return true;
    }

    void odomCallback(const nav_msgs::OdometryConstPtr& msg)
    {
        //Let's get the pose out from odometry message
        // REMEBER: on command line you can view entier msg as
        //rosmsg show nav_msgs/Odometry
        geometry_msgs::Pose pose=msg->pose.pose;
        buffer.buffer_mutex_.lock();
        buffer.poseDeq.push_back(pose);
        buffer.timeStampDeq.push_back(msg->header.stamp);
        buffer.buffer_mutex_.unlock();

    }



    void laserCallback(const sensor_msgs::LaserScanConstPtr& msg)
    {
        //! Below sample cicrulates through the scan and finds closest point to robot
        double closest_point=msg->range_max;
        double angle=0;
        double x,y;
        for (unsigned int idx=0 ; idx < msg->ranges.size() ; idx++){
            if(msg->ranges.at(idx)<closest_point){
                closest_point=msg->ranges.at(idx);
                angle=msg->angle_min+(idx*msg->angle_increment);
            }
        }
        ros::Time timeLaser = msg->header.stamp;
        x = closest_point * cos(angle);
        y = closest_point * sin(angle);
        std::cout << timeLaser << " L: [d,theta,x,y]=[" << closest_point << "," << angle << "," << x << "," << y << "]" << std::endl;
    }

    void imageCallback(const sensor_msgs::ImageConstPtr& msg)
    {
        //! Below code pushes the image and time to a deque, to share across threads
        try
        {
          if (enc::isColor(msg->encoding))
            cvPtr_ = cv_bridge::toCvCopy(msg, enc::BGR8);
          else
            cvPtr_ = cv_bridge::toCvCopy(msg, enc::MONO8);
        }
        catch (cv_bridge::Exception& e)
        {
          ROS_ERROR("cv_bridge exception: %s", e.what());
          return;
        }

        imageBuffer.buffer_mutex_.lock();
        imageBuffer.imageDeq.push_back(cvPtr_->image);
        imageBuffer.timeStampDeq.push_back(msg->header.stamp);
        if(imageBuffer.imageDeq.size()>2){
            imageBuffer.imageDeq.pop_front();
            imageBuffer.timeStampDeq.pop_front();
        }
        imageBuffer.buffer_mutex_.unlock();

    }


    void seperateThread() {
       /**
        * The below loop runs until ros is shutdown, to ensure this thread does not remain
        * a zombie thread
        *
        * The loop locks the buffer, checks the size
        * And then pulls items: the pose and timer_t
        * You can think if these could have been combined into one ...
        */

        double yaw,x,y;
        /// The below gets the current Ros Time
        ros::Time timeOdom = ros::Time::now();;
        ros::Time timeImage = ros::Time::now();;
        cv::Mat image;


        while (ros::ok()) {
            int deqSz =-1;

            buffer.buffer_mutex_.lock();
            deqSz = buffer.poseDeq.size();
            if (deqSz > 0) {
                geometry_msgs::Pose pose=buffer.poseDeq.front();
                yaw = tf::getYaw(pose.orientation);
                x = pose.position.x;
                y = pose.position.y;
                timeOdom = buffer.timeStampDeq.front();
                buffer.poseDeq.pop_front();
                buffer.timeStampDeq.pop_front();
            }
            buffer.buffer_mutex_.unlock();

            //! Lock image buffer, take one message from deque and unlock it
            imageBuffer.buffer_mutex_.lock();
            if(imageBuffer.imageDeq.size()>0){
                image = imageBuffer.imageDeq.front();
                timeImage = imageBuffer.timeStampDeq.front();
                imageBuffer.imageDeq.pop_front();
                imageBuffer.timeStampDeq.pop_front();
            }
            imageBuffer.buffer_mutex_.unlock();

            //Let's do something with the incoming ogMap now;
            //on every 100 iterations
            if (count_>100){
               count_=0;
               if(!image.empty()){
                   cv::Mat rgbImage;
                   cv::cvtColor(image,rgbImage,CV_GRAY2RGB);
                   if (image.rows > 60 && image.cols > 60)
                    //cv::circle(rgbImage, cv::Point((x/resolution_)+(image.rows/2), (y/resolution_)+(image.cols/2)), 7, CV_RGB(255,0,0),-1);
                    cv::circle(rgbImage, cv::Point((image.rows/2), (image.cols/2)), 7, CV_RGB(0,0,255),-1);
                    std::cout << timeOdom  << " O: [x,y,yaw]=[" <<
                                x << "," << y << "," << yaw << "]" << std::endl;
                    std::cout << " pos [x,y]=[" << (x/resolution_) << ","  << (y/resolution_) << "] " <<
                                              " pos [x,y]=[" << (x/resolution_)+(image.rows/2) << "," << (y/resolution_)+(image.cols/2) << "]"<< std::endl;

                    // Update GUI Window
                    cv::imshow("view", image);
                    cv::waitKey(5);

                    sensor_msgs::ImagePtr msg = cv_bridge::CvImage(std_msgs::Header(), "rgb8", rgbImage).toImageMsg();
                    image_pub_.publish(msg);

                }
            }
            else{
                count_++;
                 // This delay slows the loop down for the sake of readability
                std::this_thread::sleep_for (std::chrono::milliseconds(10));
            }
        }
    }

};


int main(int argc, char **argv)
{


  /**
   * The ros::init() function needs to see argc and argv so that it can perform
   * any ROS arguments and name remapping that were provided at the command line. For programmatic
   * remappings you can use a different version of init() which takes remappings
   * directly, but for most command-line programs, passing argc and argv is the easiest
   * way to do it.  The third argument to init() is the name of the node.
   *
   * You must call one of the versions of ros::init() before using any other
   * part of the ROS system.
   */
  ros::init(argc, argv, "gazebo_retrieve");

  /**
   * NodeHandle is the main access point to communications with the ROS system.
   * The first NodeHandle constructed will fully initialize this node, and the last
   * NodeHandle destructed will close down the node.
   */
  ros::NodeHandle nh;

  /**
   * Let's start seperate thread first, to do that we need to create object
   * and thereafter start the thread on teh function desired
   */
  std::shared_ptr<GazeboRetrieve> gc(new GazeboRetrieve(nh));
  std::thread t(&GazeboRetrieve::seperateThread,gc);

  /**
   * ros::spin() will enter a loop, pumping callbacks.  With this version, all
   * callbacks will be called from within this thread (the main one).  ros::spin()
   * will exit when Ctrl-C is pressed, or the node is shutdown by the master.
   */
  ros::spin();

  /**
   * Let's cleanup everything, shutdown ros and join the thread
   */
  ros::shutdown();
  t.join();

  return 0;
}

Thank you in advance.

Asked by Zaz on 2017-10-27 13:25:05 UTC

Comments

Can you please leave those unnecessary lines of comments? It's hard to read the code if lots of the stuff is just comment.

Asked by l4ncelot on 2017-10-27 13:53:51 UTC

Sorry for that. Will keep that in mind for the future post

Asked by Zaz on 2017-10-29 23:29:32 UTC

You can edit your question any time with edit button.

Asked by l4ncelot on 2017-10-30 02:25:05 UTC

Answers