From 2ef03f4a27a45bb78ab27f5b31652426d7f325a2 Mon Sep 17 00:00:00 2001 From: Robin Vanhove Date: Fri, 13 Oct 2017 18:20:29 +0200 Subject: [PATCH] dev --- .gitignore | 1 + CMakeLists.txt | 117 +----- README.md | 44 +++ launch/server.launch | 1 + scripts/make_library.py | 8 +- src/ros_lib/ros/node_handle.h | 40 ++- src/ros_lib/ros/service_client.h | 12 +- src/ros_lib/ros/service_server.h | 46 +-- .../MessageReceive.pro => Basic/Basic.pro} | 12 +- test/Basic/Basic.pro.user | 276 ++++++++++++++ test/{MessageReceive => Basic}/main.cpp | 0 test/{MessageReceive => Basic}/node.cpp | 14 +- test/{MessageReceive => Basic}/node.h | 4 + .../Basic.pro.user} | 80 ++++- test/LoopbackTest/LoopbackTest.pro | 35 ++ test/LoopbackTest/LoopbackTest.pro.user | 336 ++++++++++++++++++ .../testdrive.cpp => LoopbackTest/main.cpp} | 55 +-- test/LoopbackTest/node.cpp | 49 +++ test/LoopbackTest/node.h | 34 ++ test/LoopbackTest/server.launch | 10 + test/TestDrive/readme.md | 24 -- 21 files changed, 934 insertions(+), 264 deletions(-) create mode 100644 .gitignore create mode 100644 README.md rename test/{MessageReceive/MessageReceive.pro => Basic/Basic.pro} (55%) create mode 100644 test/Basic/Basic.pro.user rename test/{MessageReceive => Basic}/main.cpp (100%) rename test/{MessageReceive => Basic}/node.cpp (67%) rename test/{MessageReceive => Basic}/node.h (73%) rename test/{MessageReceive/MessageReceive.pro.user => LoopbackTest/Basic.pro.user} (72%) create mode 100644 test/LoopbackTest/LoopbackTest.pro create mode 100644 test/LoopbackTest/LoopbackTest.pro.user rename test/{TestDrive/testdrive.cpp => LoopbackTest/main.cpp} (56%) create mode 100644 test/LoopbackTest/node.cpp create mode 100644 test/LoopbackTest/node.h create mode 100644 test/LoopbackTest/server.launch delete mode 100644 test/TestDrive/readme.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cf25ac6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +CMakeLists.txt.user* diff --git a/CMakeLists.txt b/CMakeLists.txt index eeb7590..1157b5e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,119 +1,10 @@ -cmake_minimum_required(VERSION 2.8.3) +cmake_minimum_required(VERSION 2.8.11) project(rosserial_qt) -## 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 - roscpp - rospy - std_msgs -) +add_definitions(-std=c++11) -## System dependencies are found with CMake's conventions -# find_package(Boost REQUIRED COMPONENTS system) +find_package(catkin REQUIRED COMPONENTS roscpp rosserial_msgs rosserial_python rosserial_server rostest std_msgs) +catkin_package() -## 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() -################################### -## 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 rosserial_qt -# CATKIN_DEPENDS message_runtime -# DEPENDS system_lib -) - -########### -## Build ## -########### - -## Specify additional locations of header files -## Your package locations should be listed before other locations -# include_directories(include) - -## Declare a C++ library -# add_library(rosserial_qt -# src/${PROJECT_NAME}/rosserial_qt.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(rosserial_qt ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) - -## Declare a C++ executable -# add_executable(rosserial_qt_node src/rosserial_qt_node.cpp) - -## Add cmake target dependencies of the executable -## same as for the library above -# add_dependencies(rosserial_qt_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) - -## Specify libraries to link a library or executable target against -# target_link_libraries(rosserial_qt_node -# ${catkin_LIBRARIES} -# ) - -############# -## Install ## -############# - -# all install targets should use catkin DESTINATION variables -# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html - -## Mark executable scripts (Python etc.) for installation -## in contrast to setup.py, you can choose the destination -# install(PROGRAMS -# scripts/make_library.py -# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} -# ) - -## Mark executables and/or libraries for installation -# install(TARGETS rosserial_qt rosserial_qt_node -# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} -# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} -# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} -# ) - -## Mark cpp header files for installation -# install(DIRECTORY include/${PROJECT_NAME}/ -# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} -# FILES_MATCHING PATTERN "*.h" -# PATTERN ".svn" EXCLUDE -# ) - -## Mark other files for installation (e.g. launch and bag files, etc.) -# install(FILES -# # myfile1 -# # myfile2 -# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} -# ) - -# install(DIRECTORY -# src/ros_lib -# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/src -# ) - -############# -## Testing ## -############# - -## Add gtest based cpp test target and link libraries -# catkin_add_gtest(${PROJECT_NAME}-test test/test_rosserial_qt.cpp) -# if(TARGET ${PROJECT_NAME}-test) -# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME}) -# endif() - -## Add folders to be run by python nosetests -# catkin_add_nosetests(test) diff --git a/README.md b/README.md new file mode 100644 index 0000000..56a0033 --- /dev/null +++ b/README.md @@ -0,0 +1,44 @@ +# rosserial_qt + +Client implementation for rosserial using the multi-platform Qt library. +For the moment it only supports TCP/IP, but it should be easily adapted to UDP (using QUdpSocket) or serial port (using QSerialPort) communications. + +## Usage + +1. Generate the source files by running `rosrun rosserial_qt make_library.py ` +2. Compile your client application using the library. You should add the roslib library to you include path, and add the .cpp files to your source files. + +Remarks: +* Unlike other clients of rosserial, the *NodeHandle* uses a dynamically sized buffer. +* There is no need to call spinOnce() manually : the *NodeHandle* will call spinOnce() periodically and on reception of new data +* Unlike rosserial_arduino using C-style arrays, the message generation script will convert arrays to std::vector and std::array + +## Examples +Some simple examples of applications using the library are in the *test* directory + +## Performance +CPU usage is quite close to native roscpp nodes : + +## Supported platforms +This library should work on all platforms supported by Qt (Linux, Windows, macos, ios, android ...) +I have succesfully tested this library on : +* Linux +* Windows + +## Server-side configuration + +The current implementation needs the message length to be coded on 4 bytes (rosserial's default is 2 bytes). This has been implemented in rosserial-server, but has to be configured with the *msg_length_bytes* parameter. +You should also configure the receive buffer size depending of your application. +The rosserial-python server implementation will not work, as it doesn't support 4 bytes coding of the message length. + +Example launch file : +``` + + + + + + + + +``` diff --git a/launch/server.launch b/launch/server.launch index 7069d00..7a60519 100644 --- a/launch/server.launch +++ b/launch/server.launch @@ -2,6 +2,7 @@ + diff --git a/scripts/make_library.py b/scripts/make_library.py index 450f1d6..a2afe6e 100755 --- a/scripts/make_library.py +++ b/scripts/make_library.py @@ -495,6 +495,7 @@ def _write_std_includes(self, f): f.write('#include \n') f.write('#include \n') f.write('#include \n') + f.write('#include \n') f.write('#include \n') f.write('#include \n') f.write('#include \n') @@ -502,7 +503,7 @@ def _write_std_includes(self, f): f.write('#include \n') f.write('#include \n') f.write('#include \n') - f.write('#include "ros/msg.h"\n') + f.write('#include \n') def _write_msg_includes(self, f): for i in self.includes: @@ -760,7 +761,7 @@ def rosserial_client_copy_files(rospack, path): 'int32': ('int32_t', 4, PrimitiveDataType, []), 'uint32': ('uint32_t', 4, PrimitiveDataType, []), 'int64': ('int64_t', 8, PrimitiveDataType, []), - 'uint64': ('uint64_t', 4, PrimitiveDataType, []), + 'uint64': ('uint64_t', 8, PrimitiveDataType, []), 'float32': ('float', 4, PrimitiveDataType, []), 'float64': ('double', 8, PrimitiveDataType, []), 'time': ('ros::Time', 8, TimeDataType, ['ros/time']), @@ -794,7 +795,8 @@ def main(): # copy ros_lib stuff in src_dir = rospack.get_path("rosserial_qt") - #shutil.copytree(src_dir + "/src/ros_lib", path + "/ros_lib") + shutil.rmtree(path + "/ros_lib", ignore_errors = True) + shutil.copytree(src_dir + "/src/ros_lib", path + "/ros_lib") rosserial_generate(rospack, path + "/ros_lib") diff --git a/src/ros_lib/ros/node_handle.h b/src/ros_lib/ros/node_handle.h index d90b89c..c59ab9d 100644 --- a/src/ros_lib/ros/node_handle.h +++ b/src/ros_lib/ros/node_handle.h @@ -91,7 +91,10 @@ const uint8_t MODE_MESSAGE = 9; const uint8_t MODE_MSG_CHECKSUM = 10; // checksum for msg and topic id const uint32_t SERIAL_MSG_TIMEOUT = 2000; // 2000 milliseconds to recieve all of message data -const uint32_t READ_BUFFER_SIZE = 4096; +const uint32_t READ_BUFFER_SIZE = 4096; // at each read() we will ask up to READ_BUFFER_SIZE bytes + +const size_t MESSAGE_HEADER_BYTES = 10; // size of the header +const size_t BUFFER_OVER_ALLOCATION = 100*1024; //if the tx or rx buffer hasn't enough capacity, we will allocate this more using rosserial_msgs::TopicInfo; @@ -121,7 +124,7 @@ class NodeHandle : public NodeHandleBase_ * Setup Functions */ public: - NodeHandle(uint32_t input_size=10000000, uint32_t output_size=10000000, QObject *parent=0) : + NodeHandle(uint32_t input_size=10000, uint32_t output_size=10000, QObject *parent=0) : NodeHandleBase_(parent), INPUT_SIZE(input_size), OUTPUT_SIZE(output_size), @@ -272,6 +275,13 @@ class NodeHandle : public NodeHandleBase_ }else if( mode_ == MODE_TOPIC_H ){ /* top half of topic id */ topic_ += data<<8; mode_ = MODE_MESSAGE; + + // if needed expand buffer + if(bytes_ + MESSAGE_HEADER_BYTES > message_in.size()) + { + message_in.resize(bytes_ + MESSAGE_HEADER_BYTES + BUFFER_OVER_ALLOCATION); + } + if(bytes_ == 0) mode_ = MODE_MSG_CHECKSUM; }else if( mode_ == MODE_MSG_CHECKSUM ){ /* do checksum */ @@ -381,8 +391,8 @@ class NodeHandle : public NodeHandleBase_ } /* Register a new Service Server */ - template - bool advertiseService(ServiceServer& srv){ + template + bool advertiseService(ServiceServer& srv){ bool v = advertise(srv.pub); size_t i = subscribers.size(); subscribers.push_back(static_cast(&srv)); @@ -438,13 +448,19 @@ class NodeHandle : public NodeHandleBase_ /* serialize message */ size_t expected_l = msg->serialize_size(); - if( expected_l+9 >= OUTPUT_SIZE ){ - logerror("Message from device dropped: message larger than buffer."); - return -1; + + if(expected_l + MESSAGE_HEADER_BYTES > message_out.size()) + { + message_out.resize(expected_l + MESSAGE_HEADER_BYTES + BUFFER_OVER_ALLOCATION); } size_t l = msg->serialize(message_out.data()+9); + if(expected_l != l) + { + logerror("Internal error : expected_l != l ; memory could be corrupted"); + } + /* setup the header */ message_out[0] = 0xff; message_out[1] = PROTOCOL_VER; @@ -463,19 +479,13 @@ class NodeHandle : public NodeHandleBase_ chk += message_out[i]; message_out[l++] = 255 - (chk%256); - if( l <= OUTPUT_SIZE ){ - hardware_.write(message_out.data(), l); - return l; - }else{ - logerror("Message from device dropped: message larger than buffer."); - return -1; - } + hardware_.write(message_out.data(), l); + return l; } private slots: void onReadyRead() { - std::cout << "ready read" << std::endl; spinOnce(); } diff --git a/src/ros_lib/ros/service_client.h b/src/ros_lib/ros/service_client.h index f247b3c..d48f164 100644 --- a/src/ros_lib/ros/service_client.h +++ b/src/ros_lib/ros/service_client.h @@ -46,11 +46,11 @@ namespace ros { template class ServiceClient : public Subscriber_ { - typedef typename MType::Request MReq; - typedef typename MType::Response MRes; - typedef std::function CallBackT; - public: + typedef typename MType::Request MReq; + typedef typename MType::Response MRes; + typedef std::function CallbackT; + ServiceClient(const char* topic_name) : pub(topic_name, rosserial_msgs::TopicInfo::ID_SERVICE_CLIENT + rosserial_msgs::TopicInfo::ID_PUBLISHER) { @@ -58,7 +58,7 @@ namespace ros { this->waiting = false; } - void call(const MReq & request, CallBackT callback) + void call(const MReq & request, CallbackT callback) { if(waiting) { @@ -88,7 +88,7 @@ namespace ros { } bool waiting; - CallBackT cb_; + CallbackT cb_; public: Publisher pub; diff --git a/src/ros_lib/ros/service_server.h b/src/ros_lib/ros/service_server.h index ee0fb3f..3e9ee40 100644 --- a/src/ros_lib/ros/service_server.h +++ b/src/ros_lib/ros/service_server.h @@ -42,43 +42,15 @@ namespace ros { - template + template class ServiceServer : public Subscriber_ { - public: - typedef void(ObjT::*CallbackT)(const MReq&, MRes&); - - ServiceServer(const char* topic_name, CallbackT cb, ObjT* obj) : - pub(topic_name, rosserial_msgs::TopicInfo::ID_SERVICE_SERVER + rosserial_msgs::TopicInfo::ID_PUBLISHER), - obj_(obj) - { - this->topic_ = topic_name; - this->cb_ = cb; - } - - // these refer to the subscriber - virtual void callback(unsigned char *data){ - req.deserialize(data); - (obj_->*cb_)(req,resp); - pub.publish(resp); - } - virtual const char * getMsgType(){ return this->req.getType(); } - virtual const char * getMsgMD5(){ return this->req.getMD5(); } - virtual int getEndpointType(){ return rosserial_msgs::TopicInfo::ID_SERVICE_SERVER + rosserial_msgs::TopicInfo::ID_SUBSCRIBER; } - - MReq req; - MRes resp; - Publisher pub; - private: - CallbackT cb_; - ObjT* obj_; - }; - template - class ServiceServer : public Subscriber_ { public: - typedef void(*CallbackT)(const MReq&, MRes&); + typedef typename MType::Request MReq; + typedef typename MType::Response MRes; + typedef std::function CallbackT; - ServiceServer(const char* topic_name, CallbackT cb) : + ServiceServer(const std::string& topic_name, CallbackT cb) : pub(topic_name, rosserial_msgs::TopicInfo::ID_SERVICE_SERVER + rosserial_msgs::TopicInfo::ID_PUBLISHER) { this->topic_ = topic_name; @@ -87,16 +59,16 @@ namespace ros { // these refer to the subscriber virtual void callback(unsigned char *data){ + MReq req; + MRes resp; req.deserialize(data); cb_(req,resp); pub.publish(&resp); } - virtual const char * getMsgType(){ return this->req.getType(); } - virtual const char * getMsgMD5(){ return this->req.getMD5(); } + virtual const std::string& getMsgType(){ return MReq::getType(); } + virtual const std::string& getMsgMD5(){ return MReq::getMD5(); } virtual int getEndpointType(){ return rosserial_msgs::TopicInfo::ID_SERVICE_SERVER + rosserial_msgs::TopicInfo::ID_SUBSCRIBER; } - MReq req; - MRes resp; Publisher pub; private: CallbackT cb_; diff --git a/test/MessageReceive/MessageReceive.pro b/test/Basic/Basic.pro similarity index 55% rename from test/MessageReceive/MessageReceive.pro rename to test/Basic/Basic.pro index 4b415b1..21ef07a 100644 --- a/test/MessageReceive/MessageReceive.pro +++ b/test/Basic/Basic.pro @@ -4,7 +4,7 @@ QT += network CONFIG += c++11 -TARGET = MessageReceive +TARGET = Basic CONFIG += console CONFIG -= app_bundle @@ -18,16 +18,8 @@ SOURCES += main.cpp \ ../../src/ros_lib/time.cpp \ ../../src/ros_lib/RosQtSocket.cpp \ node.cpp -# The following define makes your compiler emit warnings if you use -# any feature of Qt which as been marked deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 +DEFINES += QT_DEPRECATED_WARNINGS HEADERS += \ ../../src/ros_lib/ros/duration.h \ diff --git a/test/Basic/Basic.pro.user b/test/Basic/Basic.pro.user new file mode 100644 index 0000000..2fe0772 --- /dev/null +++ b/test/Basic/Basic.pro.user @@ -0,0 +1,276 @@ + + + + + + EnvironmentId + {b4f30ced-7693-4a4b-b90f-54df2b2dcced} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + + ProjectExplorer.Project.Target.0 + + Desktop + Desktop + {95f7913d-7084-4d5d-9839-c0c5e82f5474} + 0 + 0 + 0 + + /home/robopec/Projects/Phenomobile/ws_phenofield/src/rosserial_qt/test/build-Basic-Desktop-Debug + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + true + + + /home/robopec/Projects/Phenomobile/ws_phenofield/src/rosserial_qt/test/build-Basic-Desktop-Release + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + 2 + + + 0 + Deploy + + ProjectExplorer.BuildSteps.Deploy + + 1 + Deploy locally + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Basic + + Qt4ProjectManager.Qt4RunConfiguration:/home/robopec/Projects/Phenomobile/ws_phenofield/src/rosserial_qt/test/Basic/Basic.pro + true + + Basic.pro + false + + /home/robopec/Projects/Phenomobile/ws_phenofield/src/rosserial_qt/test/build-Basic-Desktop-Debug + 3768 + false + true + false + false + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 18 + + + Version + 18 + + diff --git a/test/MessageReceive/main.cpp b/test/Basic/main.cpp similarity index 100% rename from test/MessageReceive/main.cpp rename to test/Basic/main.cpp diff --git a/test/MessageReceive/node.cpp b/test/Basic/node.cpp similarity index 67% rename from test/MessageReceive/node.cpp rename to test/Basic/node.cpp index f59439b..d1ed24d 100644 --- a/test/MessageReceive/node.cpp +++ b/test/Basic/node.cpp @@ -6,13 +6,14 @@ void estimated_pose_callback (const geometry_msgs::PoseWithCovarianceStamped & p printf ("Received pose %f, %f, %f\n", pose.pose.pose.position.x, pose.pose.pose.position.y, pose.pose.pose.position.z); - std::cout << "pose : " << QJsonDocument(pose.serializeAsJson()).toJson(QJsonDocument::Indented).toStdString() << std::endl; + std::cout << "Received pose : " << QJsonDocument(pose.serializeAsJson()).toJson(QJsonDocument::Indented).toStdString() << std::endl; } Node::Node(): chatter("chatter"), poseSub("estimated_pose", &estimated_pose_callback), - serviceClient("/rosout/get_loggers") + serviceClient("/rosout/get_loggers"), + serviceServer("add_two_ints", std::bind(&Node::addTwoInts, this, std::placeholders::_1, std::placeholders::_2)) { std::string ros_master = "127.0.0.1"; @@ -27,6 +28,9 @@ Node::Node(): m_timer->start(1000); nh.serviceClient(serviceClient); + + // not supported by rosserial_server + //nh.advertiseService(serviceServer); } void Node::onTimer() @@ -44,3 +48,9 @@ void Node::onTimer() }); } +void Node::addTwoInts(const roscpp_tutorials::TwoIntsRequest &req, roscpp_tutorials::TwoIntsResponse &res) +{ + std::cout << "addTwoInts" << std::endl; + res.sum = req.a + req.b; +} + diff --git a/test/MessageReceive/node.h b/test/Basic/node.h similarity index 73% rename from test/MessageReceive/node.h rename to test/Basic/node.h index 4e50b3e..cfa9aab 100644 --- a/test/MessageReceive/node.h +++ b/test/Basic/node.h @@ -7,6 +7,7 @@ #include #include #include +#include class Node : public QObject { @@ -19,11 +20,14 @@ public slots: void onTimer(); private: + void addTwoInts(const roscpp_tutorials::TwoIntsRequest &req, roscpp_tutorials::TwoIntsResponse &res); + ros::NodeHandle nh; QTimer *m_timer; ros::Publisher< std_msgs::String > chatter; ros::Subscriber < geometry_msgs::PoseWithCovarianceStamped > poseSub; ros::ServiceClient serviceClient; + ros::ServiceServer serviceServer; }; diff --git a/test/MessageReceive/MessageReceive.pro.user b/test/LoopbackTest/Basic.pro.user similarity index 72% rename from test/MessageReceive/MessageReceive.pro.user rename to test/LoopbackTest/Basic.pro.user index a22c65e..c0dd247 100644 --- a/test/MessageReceive/MessageReceive.pro.user +++ b/test/LoopbackTest/Basic.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId @@ -59,14 +59,14 @@ ProjectExplorer.Project.Target.0 - Desktop Qt 5.9.1 GCC 64bit - Desktop Qt 5.9.1 GCC 64bit - qt.591.gcc_64_kit + Desktop + Desktop + {95f7913d-7084-4d5d-9839-c0c5e82f5474} 0 0 0 - /home/robopec/Projects/Phenomobile/ws_phenofield/src/rosserial_qt/test/build-MessageReceive-Desktop_Qt_5_9_1_GCC_64bit-Debug + /home/robopec/Projects/Phenomobile/ws_phenofield/src/rosserial_qt/test/build-Basic-Desktop-Debug true @@ -125,7 +125,67 @@ 2 true - 1 + + /home/robopec/Projects/Phenomobile/ws_phenofield/src/rosserial_qt/test/build-Basic-Desktop-Release + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + 2 0 @@ -182,15 +242,15 @@ 2 - MessageReceive + Basic - Qt4ProjectManager.Qt4RunConfiguration:/home/robopec/Projects/Phenomobile/ws_phenofield/src/rosserial_qt/test/MessageReceive/MessageReceive.pro + Qt4ProjectManager.Qt4RunConfiguration:/home/robopec/Projects/Phenomobile/ws_phenofield/src/rosserial_qt/test/Basic/Basic.pro true - MessageReceive.pro + Basic.pro false - /home/robopec/Projects/Phenomobile/ws_phenofield/src/rosserial_qt/test/build-MessageReceive-Desktop_Qt_5_9_1_GCC_64bit-Debug + 3768 false true diff --git a/test/LoopbackTest/LoopbackTest.pro b/test/LoopbackTest/LoopbackTest.pro new file mode 100644 index 0000000..cf63452 --- /dev/null +++ b/test/LoopbackTest/LoopbackTest.pro @@ -0,0 +1,35 @@ +QT += core +QT -= gui +QT += network + +CONFIG += c++11 + +TARGET = LoopbackTest +CONFIG += console +CONFIG -= app_bundle + +TEMPLATE = app + +INCLUDEPATH += ../../src/ros_lib +INCLUDEPATH += ../ros_lib + +SOURCES += main.cpp \ + ../../src/ros_lib/duration.cpp \ + ../../src/ros_lib/time.cpp \ + ../../src/ros_lib/RosQtSocket.cpp \ + node.cpp + +DEFINES += QT_DEPRECATED_WARNINGS + +HEADERS += \ + ../../src/ros_lib/ros/duration.h \ + ../../src/ros_lib/ros/msg.h \ + ../../src/ros_lib/ros/node_handle.h \ + ../../src/ros_lib/ros/publisher.h \ + ../../src/ros_lib/ros/ros.h \ + ../../src/ros_lib/ros/service_client.h \ + ../../src/ros_lib/ros/service_server.h \ + ../../src/ros_lib/ros/subscriber.h \ + ../../src/ros_lib/ros/time.h \ + ../../src/ros_lib/ros/RosQtSocket.h \ + node.h diff --git a/test/LoopbackTest/LoopbackTest.pro.user b/test/LoopbackTest/LoopbackTest.pro.user new file mode 100644 index 0000000..041c5b4 --- /dev/null +++ b/test/LoopbackTest/LoopbackTest.pro.user @@ -0,0 +1,336 @@ + + + + + + EnvironmentId + {b4f30ced-7693-4a4b-b90f-54df2b2dcced} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + + ProjectExplorer.Project.Target.0 + + Desktop + Desktop + {95f7913d-7084-4d5d-9839-c0c5e82f5474} + 0 + 0 + 0 + + /home/robopec/Projects/Phenomobile/ws_phenofield/src/rosserial_qt/test/build-LoopbackTest-Desktop-Debug + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + true + + + /home/robopec/Projects/Phenomobile/ws_phenofield/src/rosserial_qt/test/build-LoopbackTest-Desktop-Release + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + + /home/robopec/Projects/Phenomobile/ws_phenofield/src/rosserial_qt/test/build-LoopbackTest-Desktop-Profile + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + true + false + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + 3 + + + 0 + Deploy + + ProjectExplorer.BuildSteps.Deploy + + 1 + Deploy locally + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + LoopbackTest + + Qt4ProjectManager.Qt4RunConfiguration:/home/robopec/Projects/Phenomobile/ws_phenofield/src/rosserial_qt/test/LoopbackTest/LoopbackTest.pro + true + + LoopbackTest.pro + false + + /home/robopec/Projects/Phenomobile/ws_phenofield/src/rosserial_qt/test/build-LoopbackTest-Desktop-Debug + 3768 + false + true + false + false + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 18 + + + Version + 18 + + diff --git a/test/TestDrive/testdrive.cpp b/test/LoopbackTest/main.cpp similarity index 56% rename from test/TestDrive/testdrive.cpp rename to test/LoopbackTest/main.cpp index 6cb3490..8a8189c 100644 --- a/test/TestDrive/testdrive.cpp +++ b/test/LoopbackTest/main.cpp @@ -1,15 +1,15 @@ /** Software License Agreement (BSD) -\file testdrive.cpp -\authors Kareem Shehata -\copyright Copyright (c) 2014, Clearpath Robotics, Inc., All rights reserved. +\file messagereceive.cpp +\authors Robin VANHOVE +\copyright Copyright (c) 2017, Robopec, All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Clearpath Robotics nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. @@ -23,48 +23,15 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCL ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -// testdrive.cpp : An example of how to use rosserial in Windows -// - -#include "stdafx.h" -#include -#include -#include "ros.h" -#include -#include +#include "ros/ros.h" +#include +#include "node.h" using std::string; -int main (int argc, char *argv[]) +int main(int argc, char *argv[]) { - ros::NodeHandle nh; - if (argc != 2) - { - printf ("Usage: testdrive host[:port]\n"); - return 0; - } - - printf ("Connecting to server at %s\n", argv[1]); - nh.initNode (argv[1]); - - printf ("Advertising cmd_vel message\n"); - geometry_msgs::Twist twist_msg; - ros::Publisher cmd_vel_pub ("cmd_vel", &twist_msg); - nh.advertise (cmd_vel_pub); - - printf ("Go robot go!\n"); - while (1) - { - twist_msg.linear.x = 5.1; - twist_msg.linear.y = 0; - twist_msg.linear.z = 0; - twist_msg.angular.x = 0; - twist_msg.angular.y = 0; - twist_msg.angular.z = -1.8; - cmd_vel_pub.publish (&twist_msg); - - nh.spinOnce (); - Sleep (100); - } - return 0; + QCoreApplication app(argc, argv); + Node node; + return app.exec(); } diff --git a/test/LoopbackTest/node.cpp b/test/LoopbackTest/node.cpp new file mode 100644 index 0000000..2a683be --- /dev/null +++ b/test/LoopbackTest/node.cpp @@ -0,0 +1,49 @@ +#include "node.h" + +void chatter_callback (const MsgType &msg) +{ + if(msg.data == s_msg.data) + { + //std::cout << "received correct data "<< std::endl; + } + else + { + std::cout << "received incorrect data "<< std::endl; + } + //std::cout << "received : " << msg.data << std::endl; +} + +Node::Node(): + chatter("chatter"), + chatterSub("chatter_out", &chatter_callback) +{ + std::string ros_master = "127.0.0.1"; + s_msg.data.resize(SEND_SIZE); + for(size_t i=0;istart(10); +} + +void Node::onTimer() +{ + static int i=1; + i++; + + //std::cout << "Sending string with " << s_msg.data.size() << " bytes of data" << std::endl; + for(int i=0;i<10;i++) + { + chatter.publish(s_msg); + } +} + diff --git a/test/LoopbackTest/node.h b/test/LoopbackTest/node.h new file mode 100644 index 0000000..e494859 --- /dev/null +++ b/test/LoopbackTest/node.h @@ -0,0 +1,34 @@ +#ifndef NODE_H +#define NODE_H + +#include +#include "ros/ros.h" +#include + +#include +#include + +typedef std_msgs::String MsgType; +static MsgType s_msg; + +#define SEND_SIZE 50000 + +class Node : public QObject +{ + Q_OBJECT + +public: + explicit Node(); + +public slots: + void onTimer(); + +private: + ros::NodeHandle nh; + QTimer *m_timer; + ros::Publisher< MsgType > chatter; + ros::Subscriber < MsgType > chatterSub; +}; + + +#endif // NODE_H diff --git a/test/LoopbackTest/server.launch b/test/LoopbackTest/server.launch new file mode 100644 index 0000000..d5729e5 --- /dev/null +++ b/test/LoopbackTest/server.launch @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/test/TestDrive/readme.md b/test/TestDrive/readme.md deleted file mode 100644 index 7716383..0000000 --- a/test/TestDrive/readme.md +++ /dev/null @@ -1,24 +0,0 @@ -rosserial windows TestDrive -=========================== - -This is an example of how to use rosserial_windows to send commands from a -windows app to a robot. All it does is send a cmd_vel Twist to the robot -with a static set of values. This can be updated to change the values based on -joystick or keyboard inputs, or to send other messages. - -For a full tutorial see http://wiki.ros.org/rosserial_windows/Tutorials/Hello%20World - -To use the example: - -1. Create a new visual studio command line app project -2. Copy the ros_lib generated by rosserial_windows into your project -3. Copy the testdrive.cpp instead of your main cpp file -4. Add the .h and .cpp files from the *top level* of the ros_lib to your VS project (should only be WindowsSocket.h WindowsSocket.cpp duration.cpp time.cpp and ros.h) -5. Compile the project -6. Run the exe with the command line argument of the IP address of your robot -7. Watch your robot spin around! - -Some tips: - -* Do not enable unicode support. If your command line arguments are not working correctly, try turning off unicode as the character set. -* Turn off precompiled headers or WindowsSocket will not compile properly.