I've been encountering a rather puzzling issue related to the length of a Rostopic name in my ROS (Robot Operating System) setup, and I'm hoping someone can shed some light on it.
Here's the situation: I have 2 nodes (rbf_node_desired_position_pcmvn_stdp_analysis_05_ and rbf_node_desired_acceleration_pcmvn_stdp_analysis_05_ as you can see below), each with different names but all sharing the same node type (rbf_node_sync_compactDelay_EventDriven). These nodes publish data to a common Rostopic (edlut_ros_simulation_input_spike_pcmvn_stdp_analysis_05_). Additionally, I have another node that subscribes to this same Rostopic to process the data (edlut_simulator_node_pcmvn_stdp_analysis_05_). However, I've noticed a peculiar problem: this processing node can only successfully read messages published by 1 out of the 2 nodes (only messages published by rbf_node_desired_position_pcmvn_stdp_analysis_05_), despite all 2 nodes are publishing correctly to the Rostopic (I checked it with rostopic echo rostopicname
).
The peculiar part is that this problem appears to be associated with the length of the Rostopic name (edlut_ros_simulation_input_spike_pcmvn_stdp_analysis_05_). When the Rostopic name has a length of 56, 58 or 60 characters, this issue arises, causing the processing node to miss messages from one of the nodes. However, when I change the Rostopic name length to 55, 57, 59, 61, 62 or 63 characters using any arbitrary string, everything functions perfectly, and all four nodes' messages are received and processed as expected.
Another solution is to change the length of the Rosnode name (rbf_node_desired_acceleration_pcmvn_stdp_analysis_05_) of the problematic node from 53 characters to 54.
I'm uncertain whether this behavior is due to a limitation related to the length of Rostopic or Rosnode names or if there might be some internal handling or conversion of names within ROS that's causing this behavior.
Has anyone else encountered a similar issue or can offer insights into why the Rostopic name length might be affecting the communication between nodes in this manner? Any help or suggestions would be greatly appreciated.
Thank you in advance for your assistance!
EXTRA (to reproduce the problem): launch file used:
<launch>
<!-- GLOBAL PARAMETERS -->
<param name="master_clock_topic" value="/clock" type="str" />
<!-- SYNCHRONIZER NODE
It synchronizes all the other nodes so they all run at the sime time stamps.
-Clock_topics: clock signals published by the other nodes for synchronization purposes
-Checking_frequency: rate (Hz) at which the synchronizer checks if the other nodes have finished the current time step
-Step_time: size (seconds) of every simulated time step -->
<node pkg="edlut_baxter" name="synchronizer_node_pcmvn_stdp_analysis_05_" type="synchronizer_node" output="screen">
<param name="clock_topic" value="edlut_ros/clockConfirmation_pcmvn_stdp_analysis_05_" type="str" />
<param name="number_of_nodes" value="3" type="int" />
<param name="checking_frequency" value="10000.0" type="double" />
<param name="step_time" value="0.002" type="double" />
</node>
<!-- RBF DESIRED POSITION encoding module -->
<node pkg="edlut_baxter" name="rbf_node_desired_position_pcmvn_stdp_analysis_05_" type="rbf_node_sync_compactDelay_EventDriven" output="screen" clear_params="true">
<param name="output_topic" value="edlut_ros_simulation_input_spike_pcmvn_stdp_analysis_05_" type="str" />
<param name="clock_topic" value="edlut_ros/clockConfirmation_pcmvn_stdp_analysis_05_" type="str" />
<rosparam param="neuron_index_list">
[0]
</rosparam>
<param name="sampling_frequency" value="500.0" type="double" />
<param name="checking_frequency" value="1000.0" type="double" />
</node>
<!-- RBF DESIRED ACCELERATION encoding module -->
<node pkg="edlut_baxter" name="rbf_node_desired_acceleration_pcmvn_stdp_analysis_05_" type="rbf_node_sync_compactDelay_EventDriven" output="screen" clear_params="true">
<param name="output_topic" value="edlut_ros_simulation_input_spike_pcmvn_stdp_analysis_05_" type="str" />
<param name="clock_topic" value="edlut_ros/clockConfirmation_pcmvn_stdp_analysis_05_" type="str" />
<rosparam param="neuron_index_list">
[25]
</rosparam>
<param name="sampling_frequency" value="500.0" type="double" />
<param name="checking_frequency" value="1000.0" type="double" />
</node>
<!-- subscriber NODE -->
<node pkg="edlut_baxter" name="edlut_simulator_node_pcmvn_stdp_analysis_05_" type="simulator_node2" output="screen">
<param name="input_topic" value="edlut_ros_simulation_input_spike_pcmvn_stdp_analysis_05_" type="str" />
<param name="clock_topic" value="edlut_ros/clockConfirmation_pcmvn_stdp_analysis_05_" type="str" />
</node>
</launch>
synchronizer_node code:
// This is the synchronizer node. It controls that all nodes follow the same
// time evolution when running on simulation time.
// It waits for all nodes to have finished the current time step. Once they are
// all done, it tells them to execute the next time step, and so on.
#include "ros/ros.h"
#include "ros/console.h"
#include <ros/callback_queue.h>
#include "rosgraph_msgs/Clock.h"
#include <ros/subscribe_options.h>
#include "std_msgs/Bool.h"
#include <cstring>
#include <ctime>
#include <limits>
#include <signal.h>
#include <stdlib.h>
#include <cstdlib>
#include <sys/types.h>
#include <csignal>
static bool stop_simulation;
void rosShutdownHandler(int sig)
{
stop_simulation = true;
}
class ExternalClock{
private:
ros::Time received_time;
bool first_received;
int counter;
public:
ExternalClock(): received_time(0.0), first_received(false), counter(0) {}
void ClockCallback (const rosgraph_msgs::Clock& msg){
this->counter+=1;
if (this->received_time<msg.clock){
this->received_time = msg.clock;
}
return;
}
ros::Time GetLastConfirmedTime(){
return this->received_time;
}
bool FirstReceived(){
return this->first_received;
}
int GetCounter(){
return this->counter;
}
void ResetCounter(){
this->counter = 0;
}
};
int main(int argc, char **argv)
{
// Set up ROS.
ros::init(argc, argv, "synchronizer", ros::init_options::NoSigintHandler);
if( ros::console::set_logger_level(ROSCONSOLE_DEFAULT_NAME, ros::console::levels::Info) ) {
ros::console::notifyLoggerLevelsChanged();
}
ros::NodeHandle nh;
signal(SIGINT, rosShutdownHandler);
// Declare variables that can be modified by launch file or command line.
std::string synchronizing_topic, master_clock_topic;
ros::Subscriber synchronizing_subscriber;
// std::vector<ExternalClock *> clock_objects;
ExternalClock external_clock = ExternalClock();
unsigned int num_topics;
double checking_frequency, step_time;
ros::Publisher time_publisher;
// struct timespec startt, endt;
stop_simulation = false;
// Number of external nodes to synchronize
int number_of_nodes;
// Initialize node parameters from launch file or command line.
// Use a private node handle so that multiple instances of the node can be run simultaneously
// while using different parameters.
ros::NodeHandle private_node_handle_("~");
private_node_handle_.getParam("clock_topic", synchronizing_topic);
private_node_handle_.getParam("number_of_nodes", number_of_nodes);
private_node_handle_.getParam("checking_frequency", checking_frequency);
private_node_handle_.getParam("step_time", step_time);
// Get global parameter use_sim_time
nh.getParam("master_clock_topic", master_clock_topic);
// Set callback queue
ros::CallbackQueue CallbackQueue;
nh.setCallbackQueue(&CallbackQueue);
// Include the private node handle in the callback queue for the dynamic reconfigure server
private_node_handle_.setCallbackQueue(&CallbackQueue);
synchronizing_subscriber = nh.subscribe(synchronizing_topic, 1000, &ExternalClock::ClockCallback, &external_clock);
// Publisher to advertise synchronizer node clock signal. This is the clock signal that all the nodes will follow
time_publisher = nh.advertise<rosgraph_msgs::Clock>(master_clock_topic, 100);
ROS_INFO("Synchronizer node initialized.");
ros::WallRate rate(checking_frequency);
ros::WallRate init_rate(1.0);
ros::Time next_time (0.0), last_sent_time(0.0);
bool all_first_received = false;
// Message to advertise current synchronized time
rosgraph_msgs::Clock current_time;
// Publish start simulation time 0.0
current_time.clock = ros::Time(0.0);
ROS_DEBUG("Synchronizer: Publishing simulation time %f", current_time.clock.toSec());
time_publisher.publish(current_time);
// Wait until all nodes have published 0.0 time and the synchronizer has received it
// The synchronizer node keeps publishing 0.0 time until all nodes are synchronized
while(external_clock.GetCounter() != number_of_nodes){
//ROS_INFO("FIRST COUNTER = %i", external_clock.GetCounter());
CallbackQueue.callAvailable(ros::WallDuration(0.01));
ROS_DEBUG("Synchronizer: Publishing simulation time %f", current_time.clock.toSec());
time_publisher.publish(current_time);
}
external_clock.ResetCounter();
ROS_DEBUG("Synchronizer: Node synchronized");
// Time stamp for statistical purposes
ros::WallTime start = ros::WallTime::now();
int sim_colgada_counter=0;
// Synchronizer loop
while (!stop_simulation){
CallbackQueue.callAvailable(ros::WallDuration(0.004));
unsigned int finished_nodes = external_clock.GetCounter();
ROS_DEBUG("Finished nodes %i",finished_nodes);
sim_colgada_counter=sim_colgada_counter+1;
// When all nodes have finished the current time step, the synchronizer publishes the next time step
if (finished_nodes == number_of_nodes){
ROS_DEBUG("sim_colgada_counter= %i", sim_colgada_counter);
next_time += ros::Duration(step_time);
ROS_DEBUG("Synchronizer: All nodes finished. Sending new time stamp %f",next_time.toSec());
current_time.clock = next_time;
time_publisher.publish(current_time);
ROS_DEBUG("Synchronizer: Publishing next time %f", next_time.toSec());
external_clock.ResetCounter();
sim_colgada_counter=0;
}
if (sim_colgada_counter>30000){
std::system("rosnode kill --all");
}
}
ROS_INFO("Ending Synchronizer node");
// Time statistics
ros::Time sim_time = current_time.clock;
ros::WallTime end = ros::WallTime::now();
ros::WallDuration total = end - start;
ROS_INFO("Elapsed time : %f", total.toSec());
ROS_INFO("Simulated Time : %f", sim_time.toSec());
ROS_INFO("Simulation ratio: %f", sim_time.toSec() / total.toSec());
// Shutdown node
ros::shutdown();
return 0;
} // end main()
simulator_node2 code
// This is the EDLUT simulator node.
#include <ros/callback_queue.h>
#include "ros/ros.h"
#include "std_msgs/Time.h"
#include "log4cxx/logger.h"
#include "edlut_baxter/ExternalClock.h"
#include <edlut_baxter/Spike_group.h>
#include <cstring>
#include <ctime>
#include <limits>
#include <signal.h>
static bool stop_simulation;
void rosShutdownHandler(int sig)
{
stop_simulation = true;
}
void SpikeCallback(const edlut_baxter::Spike_group::ConstPtr& msg){
for (int i=0; i<msg->neuron_index.size(); i++){
ROS_DEBUG("EDLUT: Received spike: time %f and neuron %d. Current time: %f.", msg->time[i], msg->neuron_index[i], ros::Time::now().toSec());
}
}
int main(int argc, char **argv)
{
// Set up ROS.
ros::init(argc, argv, "edlut_simulator", ros::init_options::NoSigintHandler);
log4cxx::LoggerPtr my_logger = log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME);
my_logger->setLevel(ros::console::g_level_lookup[ros::console::levels::Debug]);
ros::NodeHandle nh;
ros::Subscriber input_subscriber;
signal(SIGINT, rosShutdownHandler);
// Declare variables that can be modified by launch file or command line.
std::string input_topic, clock_topic, master_clock_topic;
ros::Publisher time_publisher;
ros::Subscriber clock_subscriber;
ExternalClock ext_clock;
ros::CallbackQueue CallbackQueue;
nh.setCallbackQueue(&CallbackQueue);
struct timespec startt, controlt, endt;
stop_simulation = false;
// Initialize node parameters from launch file.
ros::NodeHandle private_node_handle_("~");
private_node_handle_.getParam("input_topic", input_topic);
private_node_handle_.getParam("clock_topic", clock_topic);
nh.getParam("master_clock_topic", master_clock_topic);
ros::SubscribeOptions subscriberOptions = ros::SubscribeOptions::create<edlut_baxter::Spike_group>(
input_topic, 10000, boost::bind(SpikeCallback, _1), ros::VoidPtr(), &CallbackQueue);
subscriberOptions.transport_hints = ros::TransportHints().unreliable().reliable().tcpNoDelay(true);
input_subscriber = nh.subscribe(subscriberOptions);
//Subscribe to synchronizer node clock and Publish edlut's node clock
//ROS_DEBUG("Simulator: Subscribing to topic /clock");
clock_subscriber = nh.subscribe(master_clock_topic, 1000, &ExternalClock::ClockCallback, &ext_clock);
// Initialize the publisher in clock topic
time_publisher = nh.advertise<rosgraph_msgs::Clock>(clock_topic, 1000, true);
//ROS_DEBUG("Simulator: Publishing simulation time to topic %s",clock_topic.c_str());
ros::Time InitSimulationRosTime;
InitSimulationRosTime = ros::Time(0.0);
clock_t starttotalt=clock();
clock_gettime(CLOCK_REALTIME, &startt);
ros::Time last_print_time (0.0), time(0.0), last_sent_time(0.0);
ros::WallRate rate(1000.0);
ros::WallRate init_rate(1.0);
// Wait until the first signal has been received from the synchronizer node
while(!ext_clock.FirstReceived()){
CallbackQueue.callAvailable(ros::WallDuration(0.001));
rosgraph_msgs::Clock current_time;
current_time.clock = ros::Time(0.0);
//ROS_DEBUG("Simulator: Publishing simulation time %f", time.toSec());
time_publisher.publish(current_time);
init_rate.sleep();
}
time = ext_clock.GetLastConfirmedTime() +ros::Duration(0.05);
//ROS_DEBUG("Simulator: Node synchronized");
while (!stop_simulation){
CallbackQueue.callAvailable(ros::WallDuration(0.003));
//ROS_DEBUG("Simulator: Running simulation until time %f", time.toSec());
if (time>=last_print_time+ros::Duration(1.0)){
//ROS_INFO("EDLUT Simulator: Simulating until time %f", time.toSec());
last_print_time = time;
}
if (time!=last_sent_time){
// Publish the simulation time
rosgraph_msgs::Clock current_time;
current_time.clock = time;
//ROS_DEBUG("Simulator: Publishing simulation time %f", time.toSec());
time_publisher.publish(current_time);
last_sent_time = time;
}
CallbackQueue.callAvailable(ros::WallDuration(0.003));
ros::Time new_time = ext_clock.GetLastConfirmedTime() +ros::Duration(0.05);
if (new_time>time){
time = new_time;
//ROS_DEBUG("Simulator: Updating simulation time until %f", time.toSec());
}
}
clock_gettime(CLOCK_REALTIME, &endt);
ros::shutdown();
return 0;
}
rbf_node_sync_compactDelay_EventDriven code:
// This is the RBF node.
#include <ros/ros.h>
#include <ros/callback_queue.h>
#include "rosgraph_msgs/Clock.h"
#include "edlut_baxter/ExternalClock.h"
#include <edlut_baxter/AnalogCompact.h>
#include <edlut_baxter/Spike_group.h>
#include <edlut_baxter/Spike.h>
#include <edlut_baxter/LearningState.h>
#include <cstring>
#include <ctime>
#include <limits>
#include <signal.h>
#include <iostream>
#include <vector>
static bool stop_node;
/*
* Create a class
*/
void rosShutdownHandler(int sig)
{
stop_node = true;
}
int main(int argc, char **argv)
{
// Set up ROS.
ros::init(argc, argv, "rbf", ros::init_options::NoSigintHandler);
if( ros::console::set_logger_level(ROSCONSOLE_DEFAULT_NAME, ros::console::levels::Debug) ) {
ros::console::notifyLoggerLevelsChanged();
}
ros::NodeHandle nh;
signal(SIGINT, rosShutdownHandler);
// Declare variables that can be modified by launch file or command line.
std::string input_topic, output_topic, clock_topic, master_clock_topic;
std::vector<int> neuron_index;
double sampling_frequency, checking_frequency;
ros::Publisher time_publisher;
ros::Subscriber clock_subscriber;
ExternalClock ext_clock;
stop_node = false;
// Initialize node parameters from launch file or command line.
// Use a private node handle so that multiple instances of the node can be run simultaneously
// while using different parameters.
ros::NodeHandle private_node_handle_("~");
private_node_handle_.getParam("output_topic", output_topic);
private_node_handle_.getParam("clock_topic", clock_topic);
private_node_handle_.getParam("neuron_index_list", neuron_index);
private_node_handle_.getParam("sampling_frequency", sampling_frequency);
private_node_handle_.getParam("checking_frequency", checking_frequency);
nh.getParam("master_clock_topic", master_clock_topic);
double sampling_period = 1.0 / sampling_frequency;
ROS_DEBUG("output topic %s \n", output_topic.c_str());
// Create the subscriber
ros::CallbackQueue CallbackQueue;
nh.setCallbackQueue(&CallbackQueue);
clock_subscriber = nh.subscribe(master_clock_topic, 1000, &ExternalClock::ClockCallback, &ext_clock);
time_publisher = nh.advertise<rosgraph_msgs::Clock>(clock_topic, 1000, true);
// Create the output spike publisher
ros::Publisher output_publisher_group = nh.advertise<edlut_baxter::Spike_group>(output_topic, 1e9);
ROS_DEBUG("RBF: Publisher created");
ros::Rate rate(sampling_frequency);
ros::Time time(0.0), last_sent_time(0.0);
ros::WallRate sim_rate(checking_frequency);
ros::WallRate init_rate(1.0);
while(!ext_clock.FirstReceived()){
CallbackQueue.callAvailable(ros::WallDuration(0.001));
rosgraph_msgs::Clock current_time;
current_time.clock = ros::Time(0.0);
//ROS_DEBUG("RBF: Publishing simulation time %f", time.toSec());
time_publisher.publish(current_time);
init_rate.sleep();
}
time = ext_clock.GetLastConfirmedTime();
while (!stop_node){
CallbackQueue.callAvailable(ros::WallDuration(0.003));
ros::Time new_time = ext_clock.GetLastConfirmedTime();
if (new_time>time){
ros::Duration new_sampling_period = new_time - time;
time = new_time;
edlut_baxter::Spike_group spike_group;
//creo vector
std::vector<unsigned int> array_neuron;
//añado numero de neurona cogido del launch
array_neuron.push_back(neuron_index[0]);
spike_group.neuron_index = array_neuron;
//creo vector
std::vector<double> array_time;
//añado tiempo
array_time.push_back(time.toSec());
spike_group.time = array_time;
for (size_t i = 0; i < spike_group.neuron_index.size(); ++i)
{
ROS_DEBUG("RBF publish neuron_index[%zu] = %u, time[%zu] = %f", i, spike_group.neuron_index[i], i, spike_group.time[i]);
}
output_publisher_group.publish(spike_group);
}
if (time!=last_sent_time){
// Publish the simulation time
rosgraph_msgs::Clock current_time;
current_time.clock = time;
time_publisher.publish(current_time);
last_sent_time = time;
}
sim_rate.sleep();
}
ros::shutdown();
return 0;
}
package.xml
<?xml version="1.0"?>
<package>
<name>edlut_baxter</name>
<version>0.0.0</version>
<description>The edlut_baxter package</description>
<!-- One maintainer tag required, multiple allowed, one person per tag -->
<!-- Example: -->
<!-- <maintainer email="[email protected]">Jane Doe</maintainer> -->
<maintainer email="[email protected]">Jesus Garrido</maintainer>
<!-- One license tag required, multiple allowed, one license per tag -->
<!-- Commonly used license strings: -->
<!-- BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
<license>TODO</license>
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<build_depend>rospy</build_depend>
<build_depend>std_msgs</build_depend>
<build_depend>message_generation</build_depend>
<build_depend>baxter_core_msgs</build_depend>
<build_depend>gazebo_ros_control</build_depend>
<build_depend>gazebo_ros</build_depend>
<run_depend>roscpp</run_depend>
<run_depend>rospy</run_depend>
<run_depend>std_msgs</run_depend>
<run_depend>baxter_core_msgs</run_depend>
<run_depend>message_generation</run_depend>
<run_depend>message_runtime</run_depend>
<run_depend>gazebo_ros</run_depend>
<run_depend>gazebo_ros_control</run_depend>
<!-- The export tag contains other, unspecified, tags -->
<export>
<!-- Other tools can request additional information be placed here -->
<gazebo_ros plugin_path="${prefix}/lib" gazebo_media_path="${prefix}" />
</export>
</package>
CMakeLists.txt
cmake_minimum_required(VERSION 3.0.2) #ros noetic http://wiki.ros.org/noetic/Migration
include ($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake)
project(edlut_baxter)
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation
message_filters
gazebo_ros
dynamic_reconfigure
baxter_core_msgs
)
# Depend on system install of Gazebo
find_package(GAZEBO REQUIRED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GAZEBO_CXX_FLAGS}")
## System dependencies are found with CMake's conventions
find_package(Boost REQUIRED COMPONENTS system thread)
find_package(OpenMP REQUIRED)
if(OPENMP_FOUND)
message(STATUS "OPENMP FOUND")
set(OpenMP_FLAGS ${OpenMP_CXX_FLAGS}) # or if you use C: ${OpenMP_C_FLAGS}
set(OpenMP_LIBS gomp)
endif()
set(WITH_CUDA TRUE) #This line sets a CMake variable WITH_CUDA to TRUE. This variable is used later to conditionally include CUDA support.
if(WITH_CUDA)
find_package(CUDA REQUIRED)
if (CUDA_FOUND)
message(STATUS "CUDA FOUND")
set(CUDA_LIBS cudart)
set(CUDA_LIB_PATH ${CUDA_TOOLKIT_ROOT_DIR}/lib64)
endif()
endif()
## Generate messages in the 'msg' folder
add_message_files(
FILES
Analog.msg
AnalogCompact.msg
Spike.msg
Spike_group.msg
LearningState.msg
AnalogCompactDelay.msg
Time.msg
FullStateCompact.msg
FullStateCompactDelay.msg
AnalogCompact_AgonistAntagonist.msg
MarkerKinematicsCompact.msg
)
## Generate added messages and services with any dependencies listed here
generate_messages(
DEPENDENCIES
std_msgs
)
################################################
## Declare ROS dynamic reconfigure parameters ##
################################################
## To declare and build dynamic reconfigure parameters within this
## package, follow these steps:
## * In the file package.xml:
## * add a build_depend and a run_depend tag for "dynamic_reconfigure"
## * In this file (CMakeLists.txt):
## * add "dynamic_reconfigure" to
## find_package(catkin REQUIRED COMPONENTS ...)
## * uncomment the "generate_dynamic_reconfigure_options" section below
## and list every .cfg file to be processed
## Generate dynamic reconfigure parameters in the 'cfg' folder
generate_dynamic_reconfigure_options(
cfg/DynParameters.cfg
cfg/DynParameters_2Entries.cfg
cfg/SynchronizerDynParameters.cfg
cfg/MaeDynParameters.cfg
cfg/WeightsDynParameters.cfg
cfg/JointSpringsExample.cfg
cfg/InterpolatorDynParameters.cfg
cfg/DelayGeneratorDynParameters.cfg
cfg/JointsPD.cfg
# cfg/DynReconf2.cfg
)
###################################
## 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 edlut_baxter
# CATKIN_DEPENDS roscpp rospy std_msgs
CATKIN_DEPENDS roscpp rospy std_msgs message_runtime baxter_core_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(
${catkin_INCLUDE_DIRS}
$ENV{EDLUT_INSTALL_DIR}/include
/home/baxter/ros_ws/devel/include
include
${Boost_INCLUDE_DIRS}
${GAZEBO_INCLUDE_DIRS}
)
link_directories(
/usr/local/lib
${Boost_LIBRARY_DIRS}
${CUDA_LIB_PATH}
${GAZEBO_LIBRARY_DIRS}
)
## Declare a C++ executable
add_executable(simulator_node2 src/simulator_node2.cpp)
add_executable(synchronizer_node src/synchronizer_node.cpp)
add_executable(rbf_node_sync_compactDelay_EventDriven src/rbf_node_sync_compactDelay_EventDriven.cpp)
target_compile_options(simulator_node2 PRIVATE ${OpenMP_FLAGS} -fPIC)
## Add cmake target dependencies of the executable
## same as for the library above
add_dependencies(simulator_node2 edlut_baxter_generate_messages_cpp)
add_dependencies(synchronizer_node edlut_baxter_generate_messages_cpp)
add_dependencies(rbf_node_sync_compactDelay_EventDriven edlut_baxter_generate_messages_cpp)
## Specify libraries to link a library or executable target against
target_link_libraries(simulator_node2
${catkin_LIBRARIES}
$ENV{EDLUT_INSTALL_DIR}/lib/libedlut.a
${OpenMP_LIBS}
${CUDA_LIBS}
)
target_link_libraries(synchronizer_node
${catkin_LIBRARIES}
${GAZEBO_LIBRARIES}
)
target_link_libraries(rbf_node_sync_compactDelay_EventDriven
${catkin_LIBRARIES}
${OpenMP_LIBS}
)
```