Commit 591ba07e authored by Valentin Platzgummer's avatar Valentin Platzgummer

123

parent e089277b
...@@ -28,11 +28,12 @@ QGCROOT = $$PWD ...@@ -28,11 +28,12 @@ QGCROOT = $$PWD
DebugBuild { DebugBuild {
DESTDIR = $${OUT_PWD}/debug DESTDIR = $${OUT_PWD}/debug
DEFINES += DEBUG DEFINES += DEBUG
DEFINES += ROS_BRIDGE_DEBUG
#DEFINES += ROS_BRIDGE_CLIENT_DEBUG #DEFINES += ROS_BRIDGE_CLIENT_DEBUG
} }
else { else {
DESTDIR = $${OUT_PWD}/release DESTDIR = $${OUT_PWD}/release
DEFINES += DEBUG DEFINES += ROS_BRIDGE_DEBUG
DEFINES += NDEBUG DEFINES += NDEBUG
} }
......
...@@ -13,6 +13,9 @@ public: ...@@ -13,6 +13,9 @@ public:
WimaPolygonArray(const WimaPolygonArray &other) : WimaPolygonArray(const WimaPolygonArray &other) :
_polygons(other._polygons), _dirty(true) _polygons(other._polygons), _dirty(true)
{} {}
~WimaPolygonArray(){
_objs.clearAndDeleteContents();
}
class QmlObjectListModel *QmlObjectListModel(){ class QmlObjectListModel *QmlObjectListModel(){
if (_dirty) if (_dirty)
...@@ -34,9 +37,9 @@ public: ...@@ -34,9 +37,9 @@ public:
private: private:
void _updateObjects(void){ void _updateObjects(void){
_objs.clear(); _objs.clearAndDeleteContents();
for (long i=0; i<_polygons.size(); ++i){ for (long i=0; i<_polygons.size(); ++i){
_objs.append(&_polygons[i]); _objs.append(new PolygonType(_polygons[i]));
} }
} }
......
This diff is collapsed.
...@@ -337,7 +337,7 @@ private slots: ...@@ -337,7 +337,7 @@ private slots:
void _snakeStoreWorkerResults (); void _snakeStoreWorkerResults ();
void _initStartSnakeWorker (); void _initStartSnakeWorker ();
void _switchSnakeManager (QVariant variant); void _switchSnakeManager (QVariant variant);
void _setupTopicService (); bool _doTopicServiceSetup();
// Periodic tasks. // Periodic tasks.
void _eventTimerHandler (void); void _eventTimerHandler (void);
// Waypoint manager handling. // Waypoint manager handling.
...@@ -407,6 +407,7 @@ private: ...@@ -407,6 +407,7 @@ private:
int _fallbackStatus; int _fallbackStatus;
ROSBridgePtr _pRosBridge; ROSBridgePtr _pRosBridge;
static StatusMap _nemoStatusMap; static StatusMap _nemoStatusMap;
bool _topicServiceSetupDone;
// Periodic tasks. // Periodic tasks.
QTimer _eventTimer; QTimer _eventTimer;
......
This diff is collapsed.
This diff is collapsed.
...@@ -20,18 +20,10 @@ bool ros_bridge::com_private::getTopic(const ros_bridge::com_private::JsonDoc &d ...@@ -20,18 +20,10 @@ bool ros_bridge::com_private::getTopic(const ros_bridge::com_private::JsonDoc &d
{ {
if ( doc.HasMember("topic") && doc["topic"].IsString() ){ if ( doc.HasMember("topic") && doc["topic"].IsString() ){
rapidjson::StringBuffer sb1;
rapidjson::Writer<rapidjson::StringBuffer> writer1(sb1);
doc.Accept(writer1);
std::cout << "getTopic doc: " << sb1.GetString() << std::endl;
rapidjson::StringBuffer sb; rapidjson::StringBuffer sb;
rapidjson::Writer<rapidjson::StringBuffer> writer(sb); rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
doc["topic"].Accept(writer); doc["topic"].Accept(writer);
topic = sb.GetString(); topic = sb.GetString();
std::cout << "getTopic topic: " << sb.GetString() << std::endl;
return true; return true;
} else } else
return false; return false;
......
#include "geopoint.h" #include "geopoint.h"
std::string ros_bridge::messages::geographic_msgs::geo_point::messageType(){ std::string ros_bridge::messages::geographic_msgs::geo_point::messageType(){
return "geometry_msgs/GeoPoint"; return "geographic_msgs/GeoPoint";
} }
...@@ -109,9 +109,6 @@ bool toJson(const T&p, rapidjson::Value &value, rapidjson::Document::AllocatorTy ...@@ -109,9 +109,6 @@ bool toJson(const T&p, rapidjson::Value &value, rapidjson::Document::AllocatorTy
auto altitude = detail::getAltitude(p, traits::Type2Type<Components>()); // If T has no member altitude() replace it by 0.0; auto altitude = detail::getAltitude(p, traits::Type2Type<Components>()); // If T has no member altitude() replace it by 0.0;
value.AddMember("altitude", rapidjson::Value().SetFloat((_Float64)altitude), allocator); value.AddMember("altitude", rapidjson::Value().SetFloat((_Float64)altitude), allocator);
rapidjson::Value jType;
jType.SetString(messageType().c_str(), allocator);
value.AddMember("type", jType, allocator);
return true; return true;
} }
......
...@@ -103,9 +103,6 @@ bool toJson(const T&p, rapidjson::Value &value, rapidjson::Document::AllocatorTy ...@@ -103,9 +103,6 @@ bool toJson(const T&p, rapidjson::Value &value, rapidjson::Document::AllocatorTy
auto z = detail::getZ(p, Type2Type<Components>()); // If T has no member z() replace it by 0. auto z = detail::getZ(p, Type2Type<Components>()); // If T has no member z() replace it by 0.
value.AddMember("z", rapidjson::Value().SetFloat(z), allocator); value.AddMember("z", rapidjson::Value().SetFloat(z), allocator);
rapidjson::Value jType;
jType.SetString(messageType().c_str(), allocator);
value.AddMember("type", jType, allocator);
return true; return true;
} }
......
...@@ -57,9 +57,6 @@ bool toJson(const PolygonType &poly, rapidjson::Value &value, rapidjson::Documen ...@@ -57,9 +57,6 @@ bool toJson(const PolygonType &poly, rapidjson::Value &value, rapidjson::Documen
} }
value.AddMember("points", points, allocator); value.AddMember("points", points, allocator);
rapidjson::Value jType;
jType.SetString(messageType().c_str(), allocator);
value.AddMember("type", jType, allocator);
return true; return true;
} }
......
...@@ -95,9 +95,6 @@ bool _toJson(const PolygonType &poly, ...@@ -95,9 +95,6 @@ bool _toJson(const PolygonType &poly,
} }
value.AddMember("header", header, allocator); value.AddMember("header", header, allocator);
value.AddMember("polygon", polygon, allocator); value.AddMember("polygon", polygon, allocator);
rapidjson::Value jType;
jType.SetString(messageType().c_str(), allocator);
value.AddMember("type", jType, allocator);
return true; return true;
} }
......
...@@ -183,10 +183,6 @@ namespace detail { ...@@ -183,10 +183,6 @@ namespace detail {
detail::likelihoodToJson(p, jLikelihood, allocator, traits::Int2Type<HasLikelihood::value>()); detail::likelihoodToJson(p, jLikelihood, allocator, traits::Int2Type<HasLikelihood::value>());
value.AddMember("likelihood", jLikelihood, allocator); value.AddMember("likelihood", jLikelihood, allocator);
rapidjson::Value jType;
jType.SetString(messageType().c_str(), allocator);
value.AddMember("type", jType, allocator);
return true; return true;
} }
......
...@@ -32,9 +32,6 @@ template <class HeartbeatType> ...@@ -32,9 +32,6 @@ template <class HeartbeatType>
bool toJson(const HeartbeatType &heartbeat, rapidjson::Value &value, rapidjson::Document::AllocatorType &allocator) bool toJson(const HeartbeatType &heartbeat, rapidjson::Value &value, rapidjson::Document::AllocatorType &allocator)
{ {
value.AddMember("status", std::int32_t(heartbeat.status()), allocator); value.AddMember("status", std::int32_t(heartbeat.status()), allocator);
rapidjson::Value jType;
jType.SetString(messageType().c_str(), allocator);
value.AddMember("type", jType, allocator);
return true; return true;
} }
......
...@@ -41,9 +41,6 @@ bool toJson(const ProgressType &p, rapidjson::Value &value, rapidjson::Document: ...@@ -41,9 +41,6 @@ bool toJson(const ProgressType &p, rapidjson::Value &value, rapidjson::Document:
jProgress.PushBack(rapidjson::Value().SetInt(std::int32_t(p.progress()[i])), allocator); jProgress.PushBack(rapidjson::Value().SetInt(std::int32_t(p.progress()[i])), allocator);
} }
value.AddMember("progress", jProgress, allocator); value.AddMember("progress", jProgress, allocator);
rapidjson::Value jType;
jType.SetString(messageType().c_str(), allocator);
value.AddMember("type", jType, allocator);
return true; return true;
} }
......
...@@ -62,9 +62,6 @@ bool toJson(const HeaderType &header, ...@@ -62,9 +62,6 @@ bool toJson(const HeaderType &header,
header.frameId().length(), header.frameId().length(),
allocator), allocator),
allocator); allocator);
rapidjson::Value jType;
jType.SetString(messageType().c_str(), allocator);
value.AddMember("type", jType, allocator);
return true; return true;
} }
......
...@@ -37,9 +37,6 @@ bool toJson(const TimeType &time, ...@@ -37,9 +37,6 @@ bool toJson(const TimeType &time,
{ {
value.AddMember("secs", rapidjson::Value().SetUint(uint32_t(time.secs())), allocator); value.AddMember("secs", rapidjson::Value().SetUint(uint32_t(time.secs())), allocator);
value.AddMember("nsecs", rapidjson::Value().SetUint(uint32_t(time.nSecs())), allocator); value.AddMember("nsecs", rapidjson::Value().SetUint(uint32_t(time.nSecs())), allocator);
rapidjson::Value jType;
jType.SetString(messageType().c_str(), allocator);
value.AddMember("type", jType, allocator);
return true; return true;
} }
......
...@@ -23,13 +23,16 @@ public: ...@@ -23,13 +23,16 @@ public:
void advertiseService(const char* service, void advertiseService(const char* service,
const char* type, const char* type,
const std::function<JsonDocUPtr(JsonDocUPtr)> &callback); const std::function<JsonDocUPtr(JsonDocUPtr)> &callback);
void advertiseTopic(const char* topic,
const char* type);
//! @brief Start ROS bridge. //! @brief Start ROS bridge.
void start(); void start();
//! @brief Stops ROS bridge. //! @brief Stops ROS bridge.
void reset(); void reset();
//! @return Returns true if connected to the rosbridge_server, false either. //! @return Returns true if connected to the rosbridge_server, false either.
//! @note This function can block up to 100ms. However normal execution time is smaller. //! @note \fn calls start().
bool connected(); bool connected();
bool isRunning(); bool isRunning();
......
...@@ -20,8 +20,6 @@ void ros_bridge::com_private::TopicPublisher::start() ...@@ -20,8 +20,6 @@ void ros_bridge::com_private::TopicPublisher::start()
return; return;
_stopped->store(false); _stopped->store(false);
_pThread = std::make_unique<std::thread>([this]{ _pThread = std::make_unique<std::thread>([this]{
// Init.
std::unordered_map<std::string, std::string> topicMap;
// Main Loop. // Main Loop.
while( !this->_stopped->load() ){ while( !this->_stopped->load() ){
std::unique_lock<std::mutex> lk(this->_mutex); std::unique_lock<std::mutex> lk(this->_mutex);
...@@ -39,38 +37,25 @@ void ros_bridge::com_private::TopicPublisher::start() ...@@ -39,38 +37,25 @@ void ros_bridge::com_private::TopicPublisher::start()
// Get topic and type from Json message and remove it. // Get topic and type from Json message and remove it.
std::string topic; std::string topic;
assert(com_private::getTopic(*pJsonDoc, topic)); bool ret = com_private::getTopic(*pJsonDoc, topic);
assert(com_private::removeTopic(*pJsonDoc)); assert(ret);
std::string type; (void)ret;
assert(com_private::getType(*pJsonDoc, type)); ret = com_private::removeTopic(*pJsonDoc);
assert(com_private::removeType(*pJsonDoc)); assert(ret);
(void)ret;
// Check if topic must be advertised.
std::string clientName = // Wait for topic (Rosbridge needs some time to process a advertise() request).
ros_bridge::com_private::_topicAdvertiserKey this->_rbc.waitForTopic(topic, [this]{
+ topic; return this->_stopped->load();
auto it = topicMap.find(clientName); });
if ( it == topicMap.end()) { // Need to advertise topic?
topicMap.insert(std::make_pair(clientName, topic));
this->_rbc.addClient(clientName);
this->_rbc.advertise(clientName, topic, type);
this->_rbc.waitForTopic(topic, [this]{
return this->_stopped->load();
}); // Wait until topic is advertised.
}
// Publish Json message. // Publish Json message.
if ( !this->_stopped->load() ) if ( !this->_stopped->load() )
this->_rbc.publish(topic, *pJsonDoc); this->_rbc.publish(topic, *pJsonDoc);
} // while loop } // while loop
#ifdef ROS_BRIDGE_DEBUG
// Tidy up.
for (auto& it : topicMap){
this->_rbc.unadvertise(it.second);
this->_rbc.removeClient(it.first);
}
std::cout << "TopicPublisher: publisher thread terminated." << std::endl; std::cout << "TopicPublisher: publisher thread terminated." << std::endl;
#endif
}); });
} }
...@@ -87,7 +72,13 @@ void ros_bridge::com_private::TopicPublisher::reset() ...@@ -87,7 +72,13 @@ void ros_bridge::com_private::TopicPublisher::reset()
return; return;
_pThread->join(); _pThread->join();
lk.lock(); lk.lock();
// Tidy up.
for (auto& it : this->_topicMap){
this->_rbc.unadvertise(it.first);
this->_rbc.removeClient(it.second);
}
this->_topicMap.clear();
_queue.clear(); _queue.clear();
} }
...@@ -95,14 +86,52 @@ void ros_bridge::com_private::TopicPublisher::publish( ...@@ -95,14 +86,52 @@ void ros_bridge::com_private::TopicPublisher::publish(
ros_bridge::com_private::JsonDocUPtr docPtr, ros_bridge::com_private::JsonDocUPtr docPtr,
const char *topic) const char *topic)
{ {
std::cout << "TopicPublisher \"topic\": " << topic << std::endl; // Check if topic was advertised.
std::string t(topic);
std::unique_lock<std::mutex> lk(this->_mutex);
auto it = this->_topicMap.find(t);
if ( it == this->_topicMap.end()) { // Not yet advertised?
lk.unlock();
#ifdef ROS_BRIDGE_DEBUG
std::cerr << "TopicPublisher: topic "
<< t << " not yet advertised" << std::endl;
#endif
return;
}
lk.unlock();
// Add topic information to json doc.
auto &allocator = docPtr->GetAllocator(); auto &allocator = docPtr->GetAllocator();
rapidjson::Value key("topic", allocator); rapidjson::Value key("topic", allocator);
rapidjson::Value value(topic, allocator); rapidjson::Value value(topic, allocator);
docPtr->AddMember(key, value, allocator); docPtr->AddMember(key, value, allocator);
std::unique_lock<std::mutex> lock(_mutex);
lk.lock();
_queue.push_back(std::move(docPtr)); _queue.push_back(std::move(docPtr));
lock.unlock(); lk.unlock();
_cv.notify_one(); // Wake publisher thread. _cv.notify_one(); // Wake publisher thread.
} }
bool ros_bridge::com_private::TopicPublisher::advertise(const char *topic, const char *type)
{
std::unique_lock<std::mutex> lk(this->_mutex);
std::string t(topic);
auto it = this->_topicMap.find(t);
if ( it == this->_topicMap.end()) { // Need to advertise topic?
std::string clientName =
std::string(ros_bridge::com_private::_topicAdvertiserKey)
+ t;
this->_topicMap.insert(std::make_pair(t, clientName));
lk.unlock();
this->_rbc.addClient(clientName);
this->_rbc.advertise(clientName, t, type);
return true;
} else {
lk.unlock();
#if ROS_BRIDGE_DEBUG
std::cerr << "TopicPublisher: topic " << topic << " already advertised" << std::endl;
#endif
return false;
}
}
...@@ -31,9 +31,12 @@ public: ...@@ -31,9 +31,12 @@ public:
void reset(); void reset();
void publish(JsonDocUPtr docPtr, const char *topic); void publish(JsonDocUPtr docPtr, const char *topic);
bool advertise(const char *topic, const char *type);
private: private:
using TopicMap = std::unordered_map<std::string, std::string>;
JsonQueue _queue; JsonQueue _queue;
TopicMap _topicMap;
std::mutex _mutex; std::mutex _mutex;
std::shared_ptr<std::atomic_bool> _stopped; std::shared_ptr<std::atomic_bool> _stopped;
RosbridgeWsClient &_rbc; RosbridgeWsClient &_rbc;
......
...@@ -32,8 +32,15 @@ void ros_bridge::ROSBridge::advertiseService(const char *service, ...@@ -32,8 +32,15 @@ void ros_bridge::ROSBridge::advertiseService(const char *service,
_server.advertiseService(service, type, callback); _server.advertiseService(service, type, callback);
} }
void ros_bridge::ROSBridge::advertiseTopic(const char *topic, const char *type)
{
_topicPublisher.advertise(topic, type);
}
void ros_bridge::ROSBridge::start() void ros_bridge::ROSBridge::start()
{ {
if ( !_stopped->load() )
return;
_stopped->store(false); _stopped->store(false);
_rbc.run(); _rbc.run();
_topicPublisher.start(); _topicPublisher.start();
...@@ -44,6 +51,8 @@ void ros_bridge::ROSBridge::start() ...@@ -44,6 +51,8 @@ void ros_bridge::ROSBridge::start()
void ros_bridge::ROSBridge::reset() void ros_bridge::ROSBridge::reset()
{ {
auto start = std::chrono::high_resolution_clock::now(); auto start = std::chrono::high_resolution_clock::now();
if ( _stopped->load() )
return;
_stopped->store(true); _stopped->store(true);
_topicPublisher.reset(); _topicPublisher.reset();
_topicSubscriber.reset(); _topicSubscriber.reset();
...@@ -56,6 +65,7 @@ void ros_bridge::ROSBridge::reset() ...@@ -56,6 +65,7 @@ void ros_bridge::ROSBridge::reset()
bool ros_bridge::ROSBridge::connected() bool ros_bridge::ROSBridge::connected()
{ {
start();
return _rbc.connected(); return _rbc.connected();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment