.
This commit is contained in:
@@ -77,7 +77,7 @@ find_package(catkin REQUIRED)
|
||||
## CATKIN_DEPENDS: catkin_packages dependent projects also need
|
||||
## DEPENDS: system dependencies of this project that dependent projects also need
|
||||
catkin_package(
|
||||
INCLUDE_DIRS include
|
||||
INCLUDE_DIRS include/${PROJECT_NAME}/
|
||||
LIBRARIES celix_framework celix_utils dependency_manager2
|
||||
CFG_EXTRAS celix-extras.cmake
|
||||
# CATKIN_DEPENDS other_catkin_pkg
|
||||
|
||||
@@ -78,7 +78,7 @@ find_package(catkin REQUIRED COMPONENTS
|
||||
## CATKIN_DEPENDS: catkin_packages dependent projects also need
|
||||
## DEPENDS: system dependencies of this project that dependent projects also need
|
||||
catkin_package(
|
||||
INCLUDE_DIRS include
|
||||
INCLUDE_DIRS include/${PROJECT_NAME}/
|
||||
# LIBRARIES hos_cosgi_common
|
||||
CATKIN_DEPENDS hos_celix
|
||||
# DEPENDS system_lib
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* cosgi_common.h
|
||||
*
|
||||
* Created on: 19.04.2015
|
||||
* Author: matzman
|
||||
*/
|
||||
|
||||
#ifndef INCLUDE_HOS_COSGI_COMMON_COSGI_CORE_H_
|
||||
#define INCLUDE_HOS_COSGI_COMMON_COSGI_CORE_H_
|
||||
|
||||
|
||||
namespace hos {
|
||||
namespace cosgi{
|
||||
|
||||
|
||||
class COSGI_Object_Interface {
|
||||
public:
|
||||
virtual ~COSGI_Object_Interface() {}
|
||||
};
|
||||
|
||||
|
||||
class COSGI_Service_Interface : public COSGI_Object_Interface {
|
||||
public:
|
||||
virtual const char* getServiceName() = 0;
|
||||
virtual void getServiceVersion(int& major, int& minor) = 0;
|
||||
};
|
||||
|
||||
|
||||
} // namespace cosgi
|
||||
} // namespace hos
|
||||
|
||||
#endif /* INCLUDE_HOS_COSGI_COMMON_COSGI_CORE_H_ */
|
||||
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* impl.h
|
||||
*
|
||||
* Created on: 09.05.2015
|
||||
* Author: matzman
|
||||
*/
|
||||
|
||||
#ifndef INCLUDE_HOS_COSGI_COMMON_HOS_COSGI_SERVICE_IMPLEMENTATION_H_
|
||||
#define INCLUDE_HOS_COSGI_COMMON_HOS_COSGI_SERVICE_IMPLEMENTATION_H_
|
||||
|
||||
#include "interface.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <mutex>
|
||||
#include <unordered_set>
|
||||
#include <unordered_map>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
namespace hos {
|
||||
namespace cosgi{
|
||||
namespace service {
|
||||
namespace implementation {
|
||||
|
||||
|
||||
template<class _Service>
|
||||
struct ServiceInfo {
|
||||
static const char* name;
|
||||
static const int major;
|
||||
static const int minor;
|
||||
};
|
||||
|
||||
|
||||
template<class _Service>
|
||||
class Service : public virtual interface::Service {
|
||||
public:
|
||||
virtual const char* getServiceName() { return ServiceInfo<_Service>::name; };
|
||||
virtual void getServiceVersion(int& major, int& minor) override {
|
||||
major = ServiceInfo<_Service>::major;
|
||||
minor = ServiceInfo<_Service>::minor;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
template <class... _Args> class Observable {};
|
||||
|
||||
|
||||
template<class _Event>
|
||||
class Observable<_Event> : public virtual interface::Observable<_Event> {
|
||||
protected:
|
||||
std::mutex _observersMutex;
|
||||
typedef interface::Observer<_Event> observer_type;
|
||||
typedef std::unordered_set<observer_type*> observers_type;
|
||||
observers_type _observers;
|
||||
public:
|
||||
virtual ~Observable() {}
|
||||
virtual void addObserver(observer_type* o) override {
|
||||
std::lock_guard<std::mutex> lock(_observersMutex);
|
||||
if (o != nullptr) {
|
||||
auto elem = _observers.find(o);
|
||||
if (elem == _observers.end()) {
|
||||
_observers.insert(o);
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void deleteObserver(observer_type* o) override {
|
||||
std::lock_guard<std::mutex> lock(_observersMutex);
|
||||
if (o != nullptr) {
|
||||
auto elem = _observers.find(o);
|
||||
if (elem != _observers.end()) {
|
||||
_observers.erase(elem);
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void deleteObservers() override {
|
||||
std::lock_guard<std::mutex> lock(_observersMutex);
|
||||
_observers.clear();
|
||||
};
|
||||
virtual size_t countObservers() override {
|
||||
std::lock_guard<std::mutex> lock(_observersMutex);
|
||||
return _observers.size();
|
||||
}
|
||||
virtual void notifyObservers(const _Event* e) override {
|
||||
std::lock_guard<std::mutex> lock(_observersMutex);
|
||||
for (auto l : _observers) {
|
||||
l->notificationReceived(this, e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
template<class _Key, class _Event>
|
||||
class Observable<_Key, _Event> : public virtual interface::Observable<_Key, _Event> {
|
||||
protected:
|
||||
std::mutex _observersMutex;
|
||||
typedef interface::Observer<_Key, _Event> observer_type;
|
||||
typedef std::unordered_multimap<_Key, observer_type*> observers_type;
|
||||
observers_type _observers;
|
||||
public:
|
||||
virtual ~Observable() {}
|
||||
virtual void addObserver(_Key k, observer_type* o) override {
|
||||
std::lock_guard<std::mutex> lock(_observersMutex);
|
||||
if (o != nullptr) {
|
||||
bool _found = false;
|
||||
auto range = _observers.equal_range(k);
|
||||
for (auto i = range.first; i != range.second; i++) {
|
||||
if (i.second == o) {
|
||||
_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!_found) {
|
||||
_observers.insert({k, o});
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void deleteObserver(_Key k, observer_type* o) override {
|
||||
std::lock_guard<std::mutex> lock(_observersMutex);
|
||||
if (o != nullptr) {
|
||||
bool _found = false;
|
||||
auto range = _observers.equal_range(k);
|
||||
for (auto i = range.first; i != range.second; i++) {
|
||||
if (i.second == o) {
|
||||
_observers.erase(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void deleteObservers() override {
|
||||
std::lock_guard<std::mutex> lock(_observersMutex);
|
||||
_observers.clear();
|
||||
}
|
||||
virtual size_t countObservers() override {
|
||||
std::lock_guard<std::mutex> lock(_observersMutex);
|
||||
return _observers.size();
|
||||
}
|
||||
void notifyObservers(_Key k, const _Event* e) override {
|
||||
std::lock_guard<std::mutex> lock(_observersMutex);
|
||||
auto ol = _observers.equal_range(k);
|
||||
std::for_each(ol.first, ol.second, [&](const typename observer_type::value_type& o) {
|
||||
o.second->notificationReceived(this, k, e);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace service
|
||||
} // namespace cosgi
|
||||
} // namespace hos
|
||||
|
||||
|
||||
#endif /* INCLUDE_HOS_COSGI_COMMON_HOS_COSGI_SERVICE_IMPLEMENTATION_H_ */
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* cosgi_common.h
|
||||
*
|
||||
* Created on: 19.04.2015
|
||||
* Author: matzman
|
||||
*/
|
||||
|
||||
#ifndef INCLUDE_HOS_COSGI_COMMON_COSGI_CORE_H_
|
||||
#define INCLUDE_HOS_COSGI_COMMON_COSGI_CORE_H_
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
|
||||
namespace hos {
|
||||
namespace cosgi{
|
||||
namespace service {
|
||||
namespace interface {
|
||||
|
||||
|
||||
class Object {
|
||||
public:
|
||||
virtual ~Object() {}
|
||||
};
|
||||
|
||||
|
||||
class Service : public virtual Object {
|
||||
public:
|
||||
virtual const char* getServiceName() = 0;
|
||||
virtual void getServiceVersion(int& major, int& minor) = 0;
|
||||
};
|
||||
|
||||
|
||||
template<class...> class Observer {};
|
||||
template<class...> class Observable {};
|
||||
template<class... _Args> class ObservableObject : public virtual Object, public virtual Observable<_Args...> {};
|
||||
template<class... _Args> class ObservableService : public virtual Service, public virtual Observable<_Args...> {};
|
||||
|
||||
|
||||
template<class _Event>
|
||||
class Observer<_Event> : public virtual Object {
|
||||
public:
|
||||
typedef Observable<_Event> observable_type;
|
||||
virtual void notificationReceived(observable_type* o, const _Event* e) = 0;
|
||||
};
|
||||
|
||||
|
||||
template<class _Key, class _Event>
|
||||
class Observer<_Key, _Event> : public virtual Object {
|
||||
public:
|
||||
typedef Observable<_Key, _Event> observable_type;
|
||||
virtual void notificationReceived(observable_type* o, const _Key& key, const _Event* e) = 0;
|
||||
};
|
||||
|
||||
|
||||
template<class _Event>
|
||||
class Observable<_Event> : public virtual Object {
|
||||
protected:
|
||||
virtual void notifyObservers(const _Event* e) = 0;
|
||||
public:
|
||||
typedef Observer<_Event> observer_type;
|
||||
virtual void addObserver(observer_type* o) = 0;
|
||||
virtual void deleteObserver(observer_type* o) = 0;
|
||||
virtual void deleteObservers() = 0;
|
||||
virtual size_t countObservers() = 0;
|
||||
};
|
||||
|
||||
|
||||
template<class _Key, class _Event>
|
||||
class Observable<_Key, _Event> : public virtual Object {
|
||||
protected:
|
||||
virtual void notifyObservers(const _Key& key, const _Event* e) = 0;
|
||||
public:
|
||||
typedef Observer<_Key, _Event> observer_type;
|
||||
virtual void addObserver(_Key& key, observer_type* o) = 0;
|
||||
virtual void deleteObserver(_Key& key, observer_type* o) = 0;
|
||||
virtual void deleteObservers() = 0;
|
||||
virtual size_t countObservers() = 0;
|
||||
};
|
||||
|
||||
|
||||
} // namespace interface
|
||||
} // namespace service
|
||||
} // namespace cosgi
|
||||
} // namespace hos
|
||||
|
||||
#endif /* INCLUDE_HOS_COSGI_COMMON_COSGI_CORE_H_ */
|
||||
@@ -89,7 +89,7 @@ find_package(Boost REQUIRED)
|
||||
## CATKIN_DEPENDS: catkin_packages dependent projects also need
|
||||
## DEPENDS: system dependencies of this project that dependent projects also need
|
||||
catkin_package(
|
||||
INCLUDE_DIRS include
|
||||
INCLUDE_DIRS include/${PROJECT_NAME}/
|
||||
# LIBRARIES hos_cosgi_devicerepository
|
||||
CATKIN_DEPENDS hos_celix hos_core_msgs hos_cosgi_launcher roscpp hos_cosgi_common hos_libvariant hos_cpp_common
|
||||
# DEPENDS system_lib
|
||||
@@ -110,7 +110,7 @@ include_directories(
|
||||
${catkin_INCLUDE_DIRS}
|
||||
${APR_INCLUDE_DIR}
|
||||
${APR_INCLUDE_DIR}/apr-1.0
|
||||
include
|
||||
include/${PROJECT_NAME}/
|
||||
${hos_libvariant_INCLUDE_DIRS}/hos_libvariant
|
||||
)
|
||||
|
||||
@@ -121,7 +121,7 @@ set(BUNDLE_NAME "hos_devicerepository")
|
||||
bundle(hos_cosgi_devicerepository
|
||||
SOURCES
|
||||
${PROJECT_SOURCE_DIR}/src/bundle_activator
|
||||
${PROJECT_SOURCE_DIR}/src/hos_devicerepository_service_impl
|
||||
${PROJECT_SOURCE_DIR}/src/hos/cosgi/service/devicerepository/devicerepository_serviceimpl
|
||||
)
|
||||
target_link_libraries(hos_cosgi_devicerepository
|
||||
${catkin_LIBRARIES}
|
||||
|
||||
+21
-26
@@ -2,33 +2,25 @@
|
||||
#define _HOS_DEVICEREPOSITORY_SERVICE_H_
|
||||
|
||||
|
||||
#include <hos_cosgi_common/cosgi_common.h>
|
||||
#include <hos_cpp_common/observable.h>
|
||||
#include <hos/common/observable.h>
|
||||
#include <hos/cosgi/service/interface.h>
|
||||
#include <Variant/Variant.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
|
||||
|
||||
// Forward declarations
|
||||
namespace libvariant {
|
||||
class Variant;
|
||||
}
|
||||
namespace hos {
|
||||
namespace cosgi {
|
||||
namespace devicerepository {
|
||||
class Device;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Service Namespace
|
||||
namespace hos {
|
||||
namespace cosgi {
|
||||
namespace service {
|
||||
namespace devicerepository {
|
||||
|
||||
// Forward declarations
|
||||
class Device;
|
||||
|
||||
using namespace ::libvariant;
|
||||
|
||||
|
||||
/**
|
||||
@@ -41,6 +33,7 @@ public:
|
||||
Device* const device;
|
||||
DeviceEvent(Device* device, EventType type) : device(device), eventType(type) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Device added
|
||||
**/
|
||||
@@ -62,9 +55,9 @@ public:
|
||||
**/
|
||||
class DeviceStatusMsgEvent : public DeviceEvent {
|
||||
public:
|
||||
DeviceStatusMsgEvent(Device* device, const libvariant::Variant& statusMsg)
|
||||
DeviceStatusMsgEvent(Device* device, const Variant statusMsg)
|
||||
: DeviceEvent(device, DeviceEvent::EventType::STATUS_UPDATED), statusMsg(statusMsg) {}
|
||||
const libvariant::Variant& statusMsg;
|
||||
const Variant statusMsg;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -72,9 +65,9 @@ public:
|
||||
**/
|
||||
class DeviceCmdMsgEvent : public DeviceEvent {
|
||||
public:
|
||||
DeviceCmdMsgEvent(Device* device, const libvariant::Variant& cmdMsg)
|
||||
DeviceCmdMsgEvent(Device* device, const Variant cmdMsg)
|
||||
: DeviceEvent(device, DeviceEvent::EventType::COMMAND_RECEIVED), cmdMsg(cmdMsg) {}
|
||||
const libvariant::Variant& cmdMsg;
|
||||
const Variant cmdMsg;
|
||||
};
|
||||
|
||||
|
||||
@@ -82,15 +75,18 @@ public:
|
||||
/**
|
||||
* Public interface of an device object
|
||||
**/
|
||||
class Device : public COSGI_Object_Interface, public common::IObservable<DeviceEvent> {
|
||||
class Device : public virtual interface::ObservableObject<DeviceEvent> {
|
||||
public:
|
||||
virtual const std::string& getDeviceID() = 0;
|
||||
virtual const std::string& getDeviceType() = 0;
|
||||
virtual const std::string& getCmdTopic() = 0;
|
||||
virtual const std::string& getStatusTopic() = 0;
|
||||
|
||||
virtual const libvariant::Variant& getCurrentState() = 0;
|
||||
virtual const libvariant::Variant& getLastState() = 0;
|
||||
virtual const Variant& getCurrentState() = 0;
|
||||
virtual const Variant& getLastState() = 0;
|
||||
|
||||
virtual void sendCommand(const Variant cmd) = 0;
|
||||
virtual bool stateChanged() = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -98,11 +94,9 @@ public:
|
||||
/**
|
||||
* Public Interface of the device repository service
|
||||
**/
|
||||
class HOSDeviceRepositoryService : public COSGI_Service_Interface, public common::IObservable<DeviceEvent> {
|
||||
class DeviceRepositoryService : public virtual interface::ObservableService<DeviceEvent> {
|
||||
public:
|
||||
static constexpr const char* SERVICE_NAME = "hos_devicerepository_service";
|
||||
static constexpr int SERVICE_VERSION_MAJOR = 1;
|
||||
static constexpr int SERVICE_VERSION_MINOR = 0;
|
||||
|
||||
virtual std::shared_ptr<Device> getDevice(std::string device_id) = 0;
|
||||
virtual size_t getDevices(std::vector<std::shared_ptr<Device>>& devices) = 0;
|
||||
@@ -111,6 +105,7 @@ public:
|
||||
|
||||
|
||||
} // namespace devicerepository
|
||||
} // namespace service
|
||||
} // namespace cosgi
|
||||
} // namespace hos
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<launch>
|
||||
<node name="cosgi_devicerepository" pkg="hos_cosgi_launcher" type="hos_cosgi_launcher" output="screen">
|
||||
<param name="autostart_bundles" value="$(find hos_cosgi_launcher)/../../build_isolated/hos_cosgi_devicerepository/hos_cosgi_devicerepository.zip $(find hos_cosgi_launcher)/../../build_isolated/hos_cosgi_rulesexecution_python/hos_cosgi_rulesexecution_python.zip $(find hos_cosgi_launcher)/../../build_isolated/hos_cosgi_rulesengine/hos_cosgi_rulesengine.zip $(find hos_cosgi_launcher)/../../devel_isolated/hos_celix/share/celix/bundles/shell.zip $(find hos_cosgi_launcher)/../../devel_isolated/hos_celix/share/celix/bundles/shell_tui.zip $(find hos_cosgi_launcher)/../../devel_isolated/hos_celix/share/celix/bundles/log_service.zip $(find hos_cosgi_launcher)/../../devel_isolated/hos_celix/share/celix/bundles/log_writer.zip $(find hos_cosgi_launcher)/../../devel_isolated/hos_celix/share/celix/bundles/log_writer_syslog.zip"/>
|
||||
<param name="autostart_bundles" value="$(find hos_cosgi_launcher)/../../build_isolated/hos_cosgi_devicerepository/hos_cosgi_devicerepository.zip $(find hos_cosgi_launcher)/../../build_isolated/hos_cosgi_ruleexecution_python/hos_cosgi_ruleexecution_python.zip $(find hos_cosgi_launcher)/../../build_isolated/hos_cosgi_ruleengine/hos_cosgi_ruleengine.zip $(find hos_cosgi_launcher)/../../devel_isolated/hos_celix/share/celix/bundles/shell.zip $(find hos_cosgi_launcher)/../../devel_isolated/hos_celix/share/celix/bundles/shell_tui.zip $(find hos_cosgi_launcher)/../../devel_isolated/hos_celix/share/celix/bundles/log_service.zip $(find hos_cosgi_launcher)/../../devel_isolated/hos_celix/share/celix/bundles/log_writer.zip $(find hos_cosgi_launcher)/../../devel_isolated/hos_celix/share/celix/bundles/log_writer_syslog.zip"/>
|
||||
</node>
|
||||
</launch>
|
||||
@@ -7,25 +7,25 @@
|
||||
#include "ros/ros.h"
|
||||
|
||||
extern "C" {
|
||||
#include "hos_celix/bundle_activator.h"
|
||||
#include "hos_celix/bundle_context.h"
|
||||
#include "celix/bundle_activator.h"
|
||||
#include "celix/bundle_context.h"
|
||||
}
|
||||
|
||||
#include <hos_cosgi_launcher/hos_core_service.h>
|
||||
#include "hos_devicerepository_service_impl.h"
|
||||
#include <hos/cosgi/service/core/core_service.h>
|
||||
#include "hos/cosgi/service/devicerepository/devicerepository_serviceimpl.h"
|
||||
|
||||
#include <hos_cpp_common/observable.h>
|
||||
#include <hos/common/observable.h>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
|
||||
using namespace hos::cosgi;
|
||||
using namespace hos::cosgi::devicerepository;
|
||||
using namespace hos::cosgi::service::devicerepository;
|
||||
|
||||
|
||||
struct UserData {
|
||||
apr_pool_t* memoryPool = nullptr;
|
||||
std::unique_ptr<HOSDeviceRepositoryServiceImpl> serviceImpl;
|
||||
std::unique_ptr<DeviceRepositoryServiceImpl> serviceImpl;
|
||||
service_registration_pt serviceReg = nullptr;
|
||||
};
|
||||
|
||||
@@ -60,11 +60,11 @@ celix_status_t bundleActivator_start(void * userData, bundle_context_pt context)
|
||||
if (myUserData->serviceReg != nullptr) {
|
||||
serviceRegistration_unregister(myUserData->serviceReg);
|
||||
}
|
||||
myUserData->serviceImpl.reset(new HOSDeviceRepositoryServiceImpl());
|
||||
myUserData->serviceImpl.reset(new DeviceRepositoryServiceImpl());
|
||||
// Get HOS Core Service
|
||||
service_reference_pt ref = nullptr;
|
||||
bundleContext_getServiceReference(context, (char*)core::HOSCoreService::SERVICE_NAME, &ref);
|
||||
core::HOSCoreService* coreService = nullptr;
|
||||
bundleContext_getServiceReference(context, (char*)service::core::CoreService::SERVICE_NAME, &ref);
|
||||
service::core::CoreService* coreService = nullptr;
|
||||
bundleContext_getService(context, ref, (void**)&coreService);
|
||||
if (coreService == nullptr) {
|
||||
ROS_ERROR("DeviceRepositoryService: Could not retrieve HOSCoreService. Are you using hos_cosgi_launcher?");
|
||||
@@ -73,7 +73,7 @@ celix_status_t bundleActivator_start(void * userData, bundle_context_pt context)
|
||||
}
|
||||
// Register hos-devicerepository-service
|
||||
if (myUserData->serviceImpl->isInitialized()) {
|
||||
bundleContext_registerService(context, (char*)HOSDeviceRepositoryService::SERVICE_NAME, myUserData->serviceImpl.get(), nullptr, &myUserData->serviceReg);
|
||||
bundleContext_registerService(context, (char*)DeviceRepositoryService::SERVICE_NAME, myUserData->serviceImpl.get(), nullptr, &myUserData->serviceReg);
|
||||
}
|
||||
ROS_INFO("DeviceRepositoryService: Bundle successfully started");
|
||||
} else {
|
||||
|
||||
+42
-31
@@ -5,8 +5,8 @@
|
||||
* Author: matzman
|
||||
*/
|
||||
|
||||
#include "hos_devicerepository_service_impl.h"
|
||||
#include <hos_cosgi_launcher/hos_core_service.h>
|
||||
#include "devicerepository_serviceimpl.h"
|
||||
#include <hos/cosgi/service/core/core_service.h>
|
||||
#include <ros/ros.h>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
@@ -17,8 +17,15 @@
|
||||
|
||||
namespace hos {
|
||||
namespace cosgi {
|
||||
namespace service {
|
||||
namespace devicerepository {
|
||||
|
||||
|
||||
template<> const char* implementation::ServiceInfo<DeviceRepositoryServiceImpl>::name = service::devicerepository::DeviceRepositoryService::SERVICE_NAME;
|
||||
template<> const int implementation::ServiceInfo<DeviceRepositoryServiceImpl>::major = 0;
|
||||
template<> const int implementation::ServiceInfo<DeviceRepositoryServiceImpl>::minor = 4;
|
||||
|
||||
|
||||
DeviceImpl::DeviceImpl(std::string deviceID, std::string type, std::string statusTopic, std::string cmdTopic)
|
||||
: deviceID(deviceID), deviceType(type), statusTopic(statusTopic), cmdTopic(cmdTopic) {
|
||||
std::cout << "GenericDeviceImpl(" << deviceID << ", " << type << ", " << statusTopic << ", " << cmdTopic << ")" << std::endl;
|
||||
@@ -38,7 +45,15 @@ void DeviceImpl::handleCommandMsg(Variant& msg) {
|
||||
notifyObservers(&event);
|
||||
}
|
||||
|
||||
void HOSDeviceRepositoryServiceImpl::setCoreService(core::HOSCoreService* coreService) {
|
||||
void DeviceImpl::sendCommand(const Variant cmd) {
|
||||
std::lock_guard<std::mutex> lock(objMutex);
|
||||
}
|
||||
|
||||
bool DeviceImpl::stateChanged() {
|
||||
return currentState == lastState;
|
||||
}
|
||||
|
||||
void DeviceRepositoryServiceImpl::setCoreService(service::core::CoreService* coreService) {
|
||||
if (coreService && !this->coreService) {
|
||||
this->coreService = coreService;
|
||||
this->nodehandle = coreService->getPrivateNodeHandle();
|
||||
@@ -49,7 +64,7 @@ void HOSDeviceRepositoryServiceImpl::setCoreService(core::HOSCoreService* coreSe
|
||||
}
|
||||
}
|
||||
|
||||
void HOSDeviceRepositoryServiceImpl::init() {
|
||||
void DeviceRepositoryServiceImpl::init() {
|
||||
nodehandle->getParam("device_repository_prefix", deviceRepositoryPrefix);
|
||||
nodehandle->getParam("hos_status_topic", hosStatusTopic);
|
||||
XmlRpc::XmlRpcValue rawValue;
|
||||
@@ -66,13 +81,13 @@ void HOSDeviceRepositoryServiceImpl::init() {
|
||||
}
|
||||
}
|
||||
}
|
||||
hosStatusSub = nodehandle->subscribe(hosStatusTopic, 1000, &HOSDeviceRepositoryServiceImpl::hosStatusMsgCallback, this);
|
||||
hosStatusSub = nodehandle->subscribe(hosStatusTopic, 1000, &DeviceRepositoryServiceImpl::hosStatusMsgCallback, this);
|
||||
schemaLoader.reset(new libvariant::HosSchemaLoader());
|
||||
initialized = true;
|
||||
ROS_INFO_STREAM("DeviceRepositoryService: Initialized and Ready.");
|
||||
}
|
||||
|
||||
void HOSDeviceRepositoryServiceImpl::addDevice(std::string name) {
|
||||
void DeviceRepositoryServiceImpl::addDevice(std::string name) {
|
||||
std::stringstream ss;
|
||||
ss << deviceRepositoryPrefix << "/" << name;
|
||||
XmlRpc::XmlRpcValue rawValue;
|
||||
@@ -80,7 +95,7 @@ void HOSDeviceRepositoryServiceImpl::addDevice(std::string name) {
|
||||
addDevice(name, rawValue);
|
||||
}
|
||||
|
||||
void HOSDeviceRepositoryServiceImpl::addDevice(std::string name, XmlRpc::XmlRpcValue& rawValue) {
|
||||
void DeviceRepositoryServiceImpl::addDevice(std::string name, XmlRpc::XmlRpcValue& rawValue) {
|
||||
std::lock_guard<std::recursive_mutex> lock(serviceMutex);
|
||||
std::string type, statusTopic, cmdTopic;
|
||||
XmlRpc::XmlRpcValue& typeRaw = rawValue["type"];
|
||||
@@ -100,31 +115,32 @@ void HOSDeviceRepositoryServiceImpl::addDevice(std::string name, XmlRpc::XmlRpcV
|
||||
cmdTopic = static_cast<std::string>(cmdTopicRaw);
|
||||
std::shared_ptr<DeviceImpl> dev = std::make_shared<DeviceImpl>(name, type, statusTopic, cmdTopic);
|
||||
devices.insert({name, dev});
|
||||
// cmd topic
|
||||
auto& entry = subscripedTopics[dev->getCmdTopic()];
|
||||
std::cout << "subCount1: " << entry.first << "." << std::endl;
|
||||
if (entry.first <= 0) {
|
||||
entry.second = nodehandle->subscribe(dev->getCmdTopic(), 1000, &HOSDeviceRepositoryServiceImpl::cmdMsgCallback, this);
|
||||
std::cout << "subscriped to " << dev->getCmdTopic() << "." << std::endl;
|
||||
}
|
||||
entry.first= entry.first + 1;
|
||||
subscripedTopics[dev->getCmdTopic()] = entry;
|
||||
|
||||
// status topic
|
||||
entry = subscripedTopics[dev->getStatusTopic()];
|
||||
std::cout << "subCount2: " << entry.first << "." << std::endl;
|
||||
auto& entry = subscripedTopics[dev->getStatusTopic()];
|
||||
if (entry.first <= 0) {
|
||||
entry.second = nodehandle->subscribe(dev->getStatusTopic(), 1000, &HOSDeviceRepositoryServiceImpl::statusMsgCallback, this);
|
||||
entry.second = nodehandle->subscribe(dev->getStatusTopic(), 1000, &DeviceRepositoryServiceImpl::statusMsgCallback, this);
|
||||
std::cout << "subscriped to " << dev->getStatusTopic() << "." << std::endl;
|
||||
}
|
||||
entry.first= entry.first + 1;
|
||||
subscripedTopics[dev->getStatusTopic()] = entry;
|
||||
|
||||
// cmd topic
|
||||
auto& entry2 = subscripedTopics[dev->getCmdTopic()];
|
||||
if (entry2.first <= 0) {
|
||||
entry2.second = nodehandle->subscribe(dev->getCmdTopic(), 1000, &DeviceRepositoryServiceImpl::cmdMsgCallback, this);
|
||||
std::cout << "subscriped to " << dev->getCmdTopic() << "." << std::endl;
|
||||
}
|
||||
entry2.first= entry2.first + 1;
|
||||
subscripedTopics[dev->getCmdTopic()] = entry2;
|
||||
|
||||
// send device added event
|
||||
DeviceAddedEvent event(dev.get());
|
||||
notifyObservers(&event);
|
||||
}
|
||||
|
||||
|
||||
void HOSDeviceRepositoryServiceImpl::removeDevice(std::string name) {
|
||||
void DeviceRepositoryServiceImpl::removeDevice(std::string name) {
|
||||
std::lock_guard<std::recursive_mutex> lock(serviceMutex);
|
||||
auto& dev = devices[name];
|
||||
if (dev) {
|
||||
@@ -136,11 +152,11 @@ void HOSDeviceRepositoryServiceImpl::removeDevice(std::string name) {
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<Device> HOSDeviceRepositoryServiceImpl::getDevice(std::string device_id) {
|
||||
std::shared_ptr<Device> DeviceRepositoryServiceImpl::getDevice(std::string device_id) {
|
||||
return std::static_pointer_cast<Device>(this->devices[device_id]);
|
||||
}
|
||||
|
||||
size_t HOSDeviceRepositoryServiceImpl::getDevices(std::vector<std::shared_ptr<Device>>& devices) {
|
||||
size_t DeviceRepositoryServiceImpl::getDevices(std::vector<std::shared_ptr<Device>>& devices) {
|
||||
std::lock_guard<std::recursive_mutex> lock(serviceMutex);
|
||||
size_t retval = 0;
|
||||
for (auto item : this->devices) {
|
||||
@@ -151,13 +167,7 @@ size_t HOSDeviceRepositoryServiceImpl::getDevices(std::vector<std::shared_ptr<De
|
||||
}
|
||||
|
||||
|
||||
void HOSDeviceRepositoryServiceImpl::getServiceVersion(int& major, int& minor) {
|
||||
major = SERVICE_VERSION_MAJOR;
|
||||
minor = SERVICE_VERSION_MINOR;
|
||||
}
|
||||
|
||||
|
||||
void HOSDeviceRepositoryServiceImpl::statusMsgCallback(const hos_core_msgs::DeviceStatusUpdate::ConstPtr& msg) {
|
||||
void DeviceRepositoryServiceImpl::statusMsgCallback(const hos_core_msgs::DeviceStatusUpdate::ConstPtr& msg) {
|
||||
std::lock_guard<std::recursive_mutex> lock(serviceMutex);
|
||||
std::cout << "HOSDeviceRepositoryServiceImpl::statusMsgCallback" << std::endl;
|
||||
Variant s = schemaLoader->GetSchema(std::string("hos:schema://").append(msg->device_type).append("/status"));
|
||||
@@ -175,7 +185,7 @@ void HOSDeviceRepositoryServiceImpl::statusMsgCallback(const hos_core_msgs::Devi
|
||||
}
|
||||
}
|
||||
|
||||
void HOSDeviceRepositoryServiceImpl::cmdMsgCallback(const hos_core_msgs::DeviceCommand::ConstPtr& msg) {
|
||||
void DeviceRepositoryServiceImpl::cmdMsgCallback(const hos_core_msgs::DeviceCommand::ConstPtr& msg) {
|
||||
std::lock_guard<std::recursive_mutex> lock(serviceMutex);
|
||||
std::cout << "HOSDeviceRepositoryServiceImpl::cmdMsgCallback" << std::endl;
|
||||
Variant s = schemaLoader->GetSchema(std::string("hos:schema://").append(msg->device_type).append("/command"));
|
||||
@@ -193,7 +203,7 @@ void HOSDeviceRepositoryServiceImpl::cmdMsgCallback(const hos_core_msgs::DeviceC
|
||||
}
|
||||
}
|
||||
|
||||
void HOSDeviceRepositoryServiceImpl::hosStatusMsgCallback(const hos_core_msgs::HosStatusUpdate::ConstPtr& msg) {
|
||||
void DeviceRepositoryServiceImpl::hosStatusMsgCallback(const hos_core_msgs::HosStatusUpdate::ConstPtr& msg) {
|
||||
std::lock_guard<std::recursive_mutex> lock(serviceMutex);
|
||||
std::cout << "HOSDeviceRepositoryServiceImpl::hosStatusMsgCallback" << std::endl;
|
||||
Variant s = schemaLoader->GetSchema(std::string("hos:schema://core/msgs/hosstatusupdate"));
|
||||
@@ -230,6 +240,7 @@ void HOSDeviceRepositoryServiceImpl::hosStatusMsgCallback(const hos_core_msgs::H
|
||||
|
||||
|
||||
} // namespace devicerepository
|
||||
} // namespace service
|
||||
} // namespace cosgi
|
||||
} // namespace hos
|
||||
|
||||
+33
-31
@@ -5,11 +5,11 @@
|
||||
* Author: matzman
|
||||
*/
|
||||
|
||||
#ifndef SRC_HOS_DEVICEREPOSITORY_SERVICE_IMPL_H_
|
||||
#define SRC_HOS_DEVICEREPOSITORY_SERVICE_IMPL_H_
|
||||
#ifndef SRC_HOS_COSGI_SERVICE_DEVICEREPOSITORY_DEVICEREPOSITORY_SERVICEIMPL_H_
|
||||
#define SRC_HOS_COSGI_SERVICE_DEVICEREPOSITORY_DEVICEREPOSITORY_SERVICEIMPL_H_
|
||||
|
||||
#include <hos/cosgi/service/implementation.h>
|
||||
#include <Variant/Variant.h>
|
||||
#include <hos_cosgi_devicerepository/hos_devicerepository_service.h>
|
||||
#include <HosSchemaLoader/HosSchemaLoader.h>
|
||||
#include <mutex>
|
||||
#include <map>
|
||||
@@ -18,8 +18,7 @@
|
||||
#include <hos_core_msgs/DeviceCommand.h>
|
||||
#include <hos_core_msgs/DeviceStatusUpdate.h>
|
||||
#include <hos_core_msgs/HosStatusUpdate.h>
|
||||
#include <hos_cpp_common/observable_impl.h>
|
||||
|
||||
#include <hos/cosgi/service/devicerepository/devicerepository_service.h>
|
||||
#include <ros/ros.h>
|
||||
|
||||
|
||||
@@ -32,17 +31,20 @@ namespace XmlRpc {
|
||||
class XmlRpcValue;
|
||||
}
|
||||
namespace hos {
|
||||
namespace cosgi {
|
||||
namespace core {
|
||||
class HOSCoreService;
|
||||
}
|
||||
}
|
||||
namespace cosgi {
|
||||
namespace service {
|
||||
namespace core {
|
||||
class CoreService;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Service Namespace
|
||||
namespace hos {
|
||||
namespace cosgi {
|
||||
namespace service {
|
||||
namespace devicerepository {
|
||||
|
||||
|
||||
@@ -50,8 +52,7 @@ namespace devicerepository {
|
||||
/**
|
||||
* Device implementation
|
||||
**/
|
||||
class DeviceImpl : public Device {
|
||||
OBSERVABLE_IMPL(DeviceEvent)
|
||||
class DeviceImpl : public virtual Device, public virtual implementation::Observable<DeviceEvent> {
|
||||
private:
|
||||
std::mutex objMutex;
|
||||
std::string deviceID;
|
||||
@@ -66,13 +67,17 @@ public:
|
||||
|
||||
/* Public Service Implementations */
|
||||
|
||||
virtual const std::string& getDeviceID() { return deviceID; }
|
||||
virtual const std::string& getDeviceType() { return deviceType; }
|
||||
virtual const std::string& getCmdTopic() { return cmdTopic; }
|
||||
virtual const std::string& getStatusTopic() { return statusTopic; }
|
||||
virtual const std::string& getDeviceID() override { return deviceID; }
|
||||
virtual const std::string& getDeviceType() override { return deviceType; }
|
||||
virtual const std::string& getCmdTopic() override { return cmdTopic; }
|
||||
virtual const std::string& getStatusTopic() override { return statusTopic; }
|
||||
|
||||
virtual const Variant& getCurrentState() { return currentState; }
|
||||
virtual const Variant& getLastState() { return lastState; }
|
||||
virtual const Variant& getCurrentState() override { return currentState; }
|
||||
virtual const Variant& getLastState() override { return lastState; }
|
||||
|
||||
virtual void sendCommand(const Variant cmd) override;
|
||||
|
||||
virtual bool stateChanged() override;
|
||||
|
||||
/* Internal Stuff */
|
||||
|
||||
@@ -86,21 +91,20 @@ public:
|
||||
/**
|
||||
* Implementation of device repository service
|
||||
**/
|
||||
class HOSDeviceRepositoryServiceImpl : public HOSDeviceRepositoryService {
|
||||
OBSERVABLE_IMPL(DeviceEvent)
|
||||
class DeviceRepositoryServiceImpl;
|
||||
class DeviceRepositoryServiceImpl : public virtual DeviceRepositoryService, public virtual implementation::Service<DeviceRepositoryServiceImpl>, public virtual implementation::Observable<DeviceEvent> {
|
||||
private:
|
||||
typedef std::map<std::string, std::shared_ptr<DeviceImpl>> devicesMap_t;
|
||||
typedef std::map<std::string, std::pair<int, ros::Subscriber>> subscripedTopicMap_t;
|
||||
|
||||
std::recursive_mutex serviceMutex;
|
||||
|
||||
ros::NodeHandle* nodehandle = nullptr;
|
||||
core::HOSCoreService* coreService = nullptr;
|
||||
service::core::CoreService* coreService = nullptr;
|
||||
|
||||
std::string deviceRepositoryPrefix = "/hos/devices/repository";
|
||||
std::string hosStatusTopic = "/hos/status/updates";
|
||||
|
||||
typedef std::map<std::string, std::shared_ptr<DeviceImpl>> devicesMap_t;
|
||||
devicesMap_t devices;
|
||||
typedef std::map<std::string, std::pair<int, ros::Subscriber>> subscripedTopicMap_t;
|
||||
subscripedTopicMap_t subscripedTopics;
|
||||
ros::Subscriber hosStatusSub;
|
||||
|
||||
@@ -117,15 +121,12 @@ private:
|
||||
public:
|
||||
/* Initialization */
|
||||
|
||||
void setCoreService(core::HOSCoreService* coreService);
|
||||
void setCoreService(service::core::CoreService* coreService);
|
||||
|
||||
/* Public Service Implementations */
|
||||
|
||||
virtual std::shared_ptr<Device> getDevice(std::string device_id);
|
||||
virtual size_t getDevices(std::vector<std::shared_ptr<Device>>& devices);
|
||||
|
||||
virtual const char* getServiceName() { return SERVICE_NAME; }
|
||||
virtual void getServiceVersion(int& major, int& minor);
|
||||
virtual std::shared_ptr<Device> getDevice(std::string device_id) override;
|
||||
virtual size_t getDevices(std::vector<std::shared_ptr<Device>>& devices) override;
|
||||
|
||||
/* Message Callbacks */
|
||||
|
||||
@@ -140,8 +141,9 @@ public:
|
||||
|
||||
|
||||
} // namespace devicerepository
|
||||
} // namespace service
|
||||
} // namespace cosgi
|
||||
} // namespace hos
|
||||
|
||||
|
||||
#endif /* SRC_HOS_DEVICEREPOSITORY_SERVICE_IMPL_H_ */
|
||||
#endif /* SRC_HOS_COSGI_SERVICE_DEVICEREPOSITORY_DEVICEREPOSITORY_SERVICEIMPL_H_ */
|
||||
@@ -82,7 +82,7 @@ find_package(APR REQUIRED)
|
||||
## CATKIN_DEPENDS: catkin_packages dependent projects also need
|
||||
## DEPENDS: system dependencies of this project that dependent projects also need
|
||||
catkin_package(
|
||||
INCLUDE_DIRS include
|
||||
INCLUDE_DIRS include/${PROJECT_NAME}/
|
||||
# LIBRARIES hos_cosgi_launcher
|
||||
CATKIN_DEPENDS hos_celix hos_cosgi_common
|
||||
# DEPENDS system_lib
|
||||
@@ -103,13 +103,13 @@ include_directories(
|
||||
${catkin_INCLUDE_DIRS}
|
||||
${APR_INCLUDE_DIR}
|
||||
${APR_INCLUDE_DIR}/apr-1.0
|
||||
include
|
||||
include/${PROJECT_NAME}/
|
||||
)
|
||||
|
||||
|
||||
add_executable(hos_cosgi_launcher
|
||||
src/hos_cosgi_launcher.cpp
|
||||
src/hos_core_service_impl.cpp
|
||||
src/launcher.cpp
|
||||
src/hos/cosgi/service/core/core_serviceimpl.cpp
|
||||
)
|
||||
target_link_libraries(hos_cosgi_launcher
|
||||
${catkin_LIBRARIES}
|
||||
|
||||
+5
-7
@@ -2,8 +2,8 @@
|
||||
#define SRC_HOS_CORE_SERVICE_H_
|
||||
|
||||
|
||||
#include <hos_cosgi_common/cosgi_common.h>
|
||||
#include <hos_cpp_common/observable.h>
|
||||
#include <hos/common/observable.h>
|
||||
#include <hos/cosgi/service/interface.h>
|
||||
|
||||
|
||||
// Forward declarations
|
||||
@@ -16,6 +16,7 @@ namespace ros {
|
||||
// Service Namespace
|
||||
namespace hos {
|
||||
namespace cosgi {
|
||||
namespace service {
|
||||
namespace core {
|
||||
|
||||
|
||||
@@ -35,19 +36,16 @@ public:
|
||||
|
||||
|
||||
|
||||
class HOSCoreService : public COSGI_Service_Interface, public common::IObservable<CoreEvent> {
|
||||
class CoreService : public virtual interface::ObservableService<CoreEvent> {
|
||||
public:
|
||||
static constexpr const char* SERVICE_NAME = "hos_core_service";
|
||||
static constexpr int SERVICE_VERSION_MAJOR = 1;
|
||||
static constexpr int SERVICE_VERSION_MINOR = 0;
|
||||
|
||||
virtual ros::NodeHandle* getPublicNodeHandle() = 0;
|
||||
virtual ros::NodeHandle* getPrivateNodeHandle() = 0;
|
||||
virtual void requestShutdown() = 0;
|
||||
};
|
||||
|
||||
|
||||
} // namespace core
|
||||
} // namespace service
|
||||
} // namespace cosgi
|
||||
} // namespace hos
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* hos_core_service_impl.cpp
|
||||
*
|
||||
* Created on: 05.04.2015
|
||||
* Author: matzman
|
||||
*/
|
||||
|
||||
#include <ros/ros.h>
|
||||
#include "core_serviceimpl.h"
|
||||
|
||||
namespace hos {
|
||||
namespace cosgi{
|
||||
namespace service {
|
||||
namespace core {
|
||||
|
||||
template<> const char* implementation::ServiceInfo<CoreServiceImpl>::name = service::core::CoreService::SERVICE_NAME;
|
||||
template<> const int implementation::ServiceInfo<CoreServiceImpl>::major = 0;
|
||||
template<> const int implementation::ServiceInfo<CoreServiceImpl>::minor = 3;
|
||||
|
||||
CoreServiceImpl::CoreServiceImpl(ros::NodeHandle* publicNodeHandle, ros::NodeHandle* privateNodeHandle)
|
||||
: publicNodeHandle(publicNodeHandle), privateNodeHandle(privateNodeHandle) {}
|
||||
|
||||
|
||||
ros::NodeHandle* CoreServiceImpl::getPublicNodeHandle() {
|
||||
return publicNodeHandle;
|
||||
}
|
||||
|
||||
ros::NodeHandle* CoreServiceImpl::getPrivateNodeHandle() {
|
||||
return privateNodeHandle;
|
||||
}
|
||||
|
||||
|
||||
void CoreServiceImpl::requestShutdown() {
|
||||
ROS_INFO("Received shutdown request");
|
||||
ros::shutdown();
|
||||
}
|
||||
|
||||
|
||||
} // namespace core
|
||||
} // namespace service
|
||||
} // namespace cosgi
|
||||
} // namespace hos
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* hos_core_service_private.h
|
||||
*
|
||||
* Created on: 05.04.2015
|
||||
* Author: matzman
|
||||
*/
|
||||
|
||||
#ifndef SRC_CORE_SERVICEIMPL_H_
|
||||
#define SRC_CORE_SERVICEIMPL_H_
|
||||
|
||||
#include <hos/cosgi/service/core/core_service.h>
|
||||
#include <hos/cosgi/service/implementation.h>
|
||||
|
||||
|
||||
// Service Namespace
|
||||
namespace hos {
|
||||
namespace cosgi{
|
||||
namespace service {
|
||||
namespace core {
|
||||
|
||||
|
||||
class CoreServiceImpl;
|
||||
class CoreServiceImpl : public virtual CoreService, public virtual implementation::Service<CoreServiceImpl>, public virtual implementation::Observable<CoreEvent> {
|
||||
private:
|
||||
ros::NodeHandle* publicNodeHandle;
|
||||
ros::NodeHandle* privateNodeHandle;
|
||||
|
||||
public:
|
||||
CoreServiceImpl(ros::NodeHandle* publicNodeHandle, ros::NodeHandle* privateNodeHandle);
|
||||
|
||||
virtual ros::NodeHandle* getPublicNodeHandle();
|
||||
virtual ros::NodeHandle* getPrivateNodeHandle();
|
||||
virtual void requestShutdown();
|
||||
};
|
||||
|
||||
} // namespace core
|
||||
} // namespace service
|
||||
} // namespace cosgi
|
||||
} // namespace hos
|
||||
|
||||
|
||||
#endif /* SRC_CORE_SERVICEIMPL_H_ */
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* hos_core_service_impl.cpp
|
||||
*
|
||||
* Created on: 05.04.2015
|
||||
* Author: matzman
|
||||
*/
|
||||
|
||||
#include "hos_core_service_impl.h"
|
||||
#include <ros/ros.h>
|
||||
|
||||
namespace hos {
|
||||
namespace cosgi{
|
||||
namespace core {
|
||||
|
||||
|
||||
HOSCoreServiceImpl::HOSCoreServiceImpl(ros::NodeHandle* publicNodeHandle, ros::NodeHandle* privateNodeHandle)
|
||||
: publicNodeHandle(publicNodeHandle), privateNodeHandle(privateNodeHandle) {}
|
||||
|
||||
|
||||
ros::NodeHandle* HOSCoreServiceImpl::getPublicNodeHandle() {
|
||||
return publicNodeHandle;
|
||||
}
|
||||
|
||||
ros::NodeHandle* HOSCoreServiceImpl::getPrivateNodeHandle() {
|
||||
return privateNodeHandle;
|
||||
}
|
||||
|
||||
|
||||
void HOSCoreServiceImpl::requestShutdown() {
|
||||
ROS_INFO("Received shutdown request");
|
||||
ros::shutdown();
|
||||
}
|
||||
|
||||
void HOSCoreServiceImpl::getServiceVersion(int& major, int& minor) {
|
||||
major = SERVICE_VERSION_MAJOR;
|
||||
minor = SERVICE_VERSION_MINOR;
|
||||
}
|
||||
|
||||
|
||||
} // namespace core
|
||||
} // namespace cosgi
|
||||
} // namespace hos
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* hos_core_service_private.h
|
||||
*
|
||||
* Created on: 05.04.2015
|
||||
* Author: matzman
|
||||
*/
|
||||
|
||||
#ifndef SRC_HOS_CORE_SERVICE_IMPL_H_
|
||||
#define SRC_HOS_CORE_SERVICE_IMPL_H_
|
||||
|
||||
#include <hos_cosgi_launcher/hos_core_service.h>
|
||||
#include <hos_cpp_common/observable_impl.h>
|
||||
|
||||
|
||||
// Service Namespace
|
||||
namespace hos {
|
||||
namespace cosgi{
|
||||
namespace core {
|
||||
|
||||
|
||||
|
||||
class HOSCoreServiceImpl : public HOSCoreService {
|
||||
OBSERVABLE_IMPL(CoreEvent)
|
||||
private:
|
||||
ros::NodeHandle* publicNodeHandle;
|
||||
ros::NodeHandle* privateNodeHandle;
|
||||
|
||||
public:
|
||||
HOSCoreServiceImpl(ros::NodeHandle* publicNodeHandle, ros::NodeHandle* privateNodeHandle);
|
||||
|
||||
virtual ros::NodeHandle* getPublicNodeHandle();
|
||||
virtual ros::NodeHandle* getPrivateNodeHandle();
|
||||
virtual void requestShutdown();
|
||||
virtual const char* getServiceName() { return SERVICE_NAME; }
|
||||
virtual void getServiceVersion(int& major, int& minor);
|
||||
};
|
||||
|
||||
} // namespace core
|
||||
} // namespace cosgi
|
||||
} // namespace hos
|
||||
|
||||
|
||||
#endif /* SRC_HOS_CORE_SERVICE_IMPL_H_ */
|
||||
+8
-9
@@ -1,15 +1,14 @@
|
||||
|
||||
#include "hos_core_service_impl.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include "ros/ros.h"
|
||||
#include <apr_general.h>
|
||||
#include <apr_strings.h>
|
||||
|
||||
#include "hos/cosgi/service/core/core_serviceimpl.h"
|
||||
|
||||
extern "C" { // celix does not provide C++ ready headers
|
||||
//#include "hos_celix/celix_errno.h"
|
||||
#include "hos_celix/framework.h"
|
||||
//#include "hos_celix/bundle_context.h"
|
||||
#include "hos_celix/linked_list_iterator.h"
|
||||
#include "celix/framework.h"
|
||||
#include "celix/linked_list_iterator.h"
|
||||
}
|
||||
#include <exception>
|
||||
#include <sstream>
|
||||
@@ -18,7 +17,7 @@ extern "C" { // celix does not provide C++ ready headers
|
||||
#include <string>
|
||||
|
||||
|
||||
using namespace hos::cosgi::core;
|
||||
using namespace hos::cosgi::service::core;
|
||||
|
||||
|
||||
std::function<void(int)> signalHandler;
|
||||
@@ -103,9 +102,9 @@ int main(int argc, char **argv) {
|
||||
bundle_getContext(fwBundle, &context);
|
||||
|
||||
// Create and register hos-core-service
|
||||
HOSCoreServiceImpl hosCoreService(&rosPublicNodeHandle, &rosPrivateNodeHandle);
|
||||
CoreServiceImpl hosCoreService(&rosPublicNodeHandle, &rosPrivateNodeHandle);
|
||||
service_registration_pt reg = nullptr;
|
||||
bundleContext_registerService(context, (char*)HOSCoreService::SERVICE_NAME, static_cast<HOSCoreService*>(&hosCoreService), nullptr, ®);
|
||||
bundleContext_registerService(context, (char*)CoreService::SERVICE_NAME, static_cast<CoreService*>(&hosCoreService), nullptr, ®);
|
||||
ROS_INFO("HOS core service registered");
|
||||
|
||||
|
||||
+23
-22
@@ -1,5 +1,5 @@
|
||||
cmake_minimum_required(VERSION 2.8.3)
|
||||
project(hos_cosgi_rulesengine)
|
||||
project(hos_cosgi_ruleengine)
|
||||
|
||||
## Find catkin macros and libraries
|
||||
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
|
||||
@@ -9,9 +9,11 @@ find_package(catkin REQUIRED COMPONENTS
|
||||
hos_cosgi_common
|
||||
hos_cosgi_devicerepository
|
||||
hos_cosgi_launcher
|
||||
hos_cosgi_scripting
|
||||
hos_cpp_common
|
||||
hos_libvariant
|
||||
roscpp
|
||||
hos_cpp_cron
|
||||
)
|
||||
|
||||
## System dependencies are found with CMake's conventions
|
||||
@@ -30,7 +32,6 @@ find_package(Boost REQUIRED)
|
||||
################################################
|
||||
## 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
|
||||
@@ -88,9 +89,9 @@ find_package(Boost REQUIRED)
|
||||
## 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 hos_cosgi_rulesengine
|
||||
CATKIN_DEPENDS hos_celix hos_cosgi_common hos_cosgi_devicerepository hos_cosgi_launcher hos_cpp_common hos_libvariant roscpp
|
||||
INCLUDE_DIRS include/${PROJECT_NAME}/
|
||||
# LIBRARIES hos_cosgi_ruleengine
|
||||
CATKIN_DEPENDS hos_celix hos_cosgi_common hos_cosgi_devicerepository hos_cosgi_launcher hos_cpp_common hos_libvariant roscpp hos_cpp_cron hos_cosgi_scripting
|
||||
# DEPENDS system_lib
|
||||
)
|
||||
|
||||
@@ -109,41 +110,41 @@ include_directories(
|
||||
${catkin_INCLUDE_DIRS}
|
||||
${APR_INCLUDE_DIR}
|
||||
${APR_INCLUDE_DIR}/apr-1.0
|
||||
include
|
||||
include/${PROJECT_NAME}/
|
||||
${hos_libvariant_INCLUDE_DIRS}/hos_libvariant
|
||||
)
|
||||
|
||||
set(BUNDLE_SYMBOLICNAME "hos.hos_rulesengine")
|
||||
set(BUNDLE_SYMBOLICNAME "hos.hos_ruleengine")
|
||||
set(BUNDLE_VERSION "1.0.0")
|
||||
set(BUNDLE_NAME "hos_rulesengine")
|
||||
set(BUNDLE_NAME "hos_ruleengine")
|
||||
|
||||
bundle(hos_cosgi_rulesengine
|
||||
bundle(hos_cosgi_ruleengine
|
||||
SOURCES
|
||||
${PROJECT_SOURCE_DIR}/src/bundle_activator
|
||||
${PROJECT_SOURCE_DIR}/src/hos_rulesengine_service_impl
|
||||
${PROJECT_SOURCE_DIR}/src/rulesengine/RulePackage
|
||||
${PROJECT_SOURCE_DIR}/src/rulesengine/Rule
|
||||
${PROJECT_SOURCE_DIR}/src/rulesengine/RuleCondition
|
||||
${PROJECT_SOURCE_DIR}/src/hos/cosgi/service/ruleengine/ruleengine_serviceimpl
|
||||
${PROJECT_SOURCE_DIR}/src/hos/cosgi/service/ruleengine/rule/RulePackage
|
||||
${PROJECT_SOURCE_DIR}/src/hos/cosgi/service/ruleengine/rule/Rule
|
||||
${PROJECT_SOURCE_DIR}/src/hos/cosgi/service/ruleengine/rule/RuleCondition
|
||||
)
|
||||
target_link_libraries(hos_cosgi_rulesengine
|
||||
target_link_libraries(hos_cosgi_ruleengine
|
||||
${catkin_LIBRARIES}
|
||||
${APR_LIBRARIES}
|
||||
)
|
||||
|
||||
## Declare a cpp library
|
||||
# add_library(hos_cosgi_rulesengine
|
||||
# src/${PROJECT_NAME}/hos_cosgi_rulesengine.cpp
|
||||
# add_library(hos_cosgi_ruleengine
|
||||
# src/${PROJECT_NAME}/hos_cosgi_ruleengine.cpp
|
||||
# )
|
||||
|
||||
## Declare a cpp executable
|
||||
# add_executable(hos_cosgi_rulesengine_node src/hos_cosgi_rulesengine_node.cpp)
|
||||
# add_executable(hos_cosgi_ruleengine_node src/hos_cosgi_ruleengine_node.cpp)
|
||||
|
||||
## Add cmake target dependencies of the executable/library
|
||||
## as an example, message headers may need to be generated before nodes
|
||||
# add_dependencies(hos_cosgi_rulesengine_node hos_cosgi_rulesengine_generate_messages_cpp)
|
||||
# add_dependencies(hos_cosgi_ruleengine_node hos_cosgi_ruleengine_generate_messages_cpp)
|
||||
|
||||
## Specify libraries to link a library or executable target against
|
||||
# target_link_libraries(hos_cosgi_rulesengine_node
|
||||
# target_link_libraries(hos_cosgi_ruleengine_node
|
||||
# ${catkin_LIBRARIES}
|
||||
# )
|
||||
|
||||
@@ -158,7 +159,7 @@ install(DIRECTORY include/${PROJECT_NAME}/
|
||||
)
|
||||
|
||||
install(FILES
|
||||
${CMAKE_BINARY_DIR}/hos_cosgi_rulesengine.zip
|
||||
${CMAKE_BINARY_DIR}/hos_cosgi_ruleengine.zip
|
||||
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/bundles
|
||||
)
|
||||
|
||||
@@ -173,7 +174,7 @@ install(FILES
|
||||
# )
|
||||
|
||||
## Mark executables and/or libraries for installation
|
||||
# install(TARGETS hos_cosgi_rulesengine hos_cosgi_rulesengine_node
|
||||
# install(TARGETS hos_cosgi_ruleengine hos_cosgi_ruleengine_node
|
||||
# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
|
||||
# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
|
||||
# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
|
||||
@@ -198,7 +199,7 @@ install(FILES
|
||||
#############
|
||||
|
||||
## Add gtest based cpp test target and link libraries
|
||||
# catkin_add_gtest(${PROJECT_NAME}-test test/test_hos_cosgi_rulesengine.cpp)
|
||||
# catkin_add_gtest(${PROJECT_NAME}-test test/test_hos_cosgi_ruleengine.cpp)
|
||||
# if(TARGET ${PROJECT_NAME}-test)
|
||||
# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
|
||||
# endif()
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* hos_ruleengine_service.h
|
||||
*
|
||||
* Created on: 26.04.2015
|
||||
* Author: matzman
|
||||
*/
|
||||
|
||||
#ifndef INCLUDE_HOS_COSGI_RULEENGINE_HOS_COSGI_SERVICE_RULEENGINE_RULEENGINE_SERVICE_H_
|
||||
#define INCLUDE_HOS_COSGI_RULEENGINE_HOS_COSGI_SERVICE_RULEENGINE_RULEENGINE_SERVICE_H_
|
||||
|
||||
|
||||
#include <hos/common/observable.h>
|
||||
#include <hos/cosgi/service/interface.h>
|
||||
|
||||
|
||||
namespace hos {
|
||||
namespace cosgi {
|
||||
namespace service {
|
||||
namespace ruleengine {
|
||||
|
||||
|
||||
class RuleEngineService : public virtual interface::Service {
|
||||
public:
|
||||
static constexpr const char* SERVICE_NAME = "hos_ruleengine_service";
|
||||
};
|
||||
|
||||
|
||||
} // namespace ruleengine
|
||||
} // namespace service
|
||||
} // namespace cosgi
|
||||
} // namespace hos
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* INCLUDE_HOS_COSGI_RULEENGINE_HOS_COSGI_SERVICE_RULEENGINE_RULEENGINE_SERVICE_H_ */
|
||||
@@ -0,0 +1,8 @@
|
||||
<launch>
|
||||
<group ns="/hos/rules/ruleengine0">
|
||||
<param name="rulepkg01" textfile="$(find hos_cosgi_ruleengine)/test/rulepkg01.json"/>
|
||||
</group>
|
||||
<node name="cosgi_ruleengine" pkg="hos_cosgi_launcher" type="hos_cosgi_launcher" output="screen">
|
||||
<param name="autostart_bundles" value="$(find hos_cosgi_launcher)/../../build_isolated/hos_cosgi_devicerepository/hos_cosgi_devicerepository.zip $(find hos_cosgi_launcher)/../../build_isolated/hos_cosgi_ruleengine/hos_cosgi_rulesngine.zip $(find hos_cosgi_launcher)/../../devel_isolated/hos_celix/share/celix/bundles/shell.zip $(find hos_cosgi_launcher)/../../devel_isolated/hos_celix/share/celix/bundles/shell_tui.zip $(find hos_cosgi_launcher)/../../devel_isolated/hos_celix/share/celix/bundles/log_service.zip $(find hos_cosgi_launcher)/../../devel_isolated/hos_celix/share/celix/bundles/log_writer.zip $(find hos_cosgi_launcher)/../../devel_isolated/hos_celix/share/celix/bundles/log_writer_syslog.zip"/>
|
||||
</node>
|
||||
</launch>
|
||||
+11
-5
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0"?>
|
||||
<package>
|
||||
<name>hos_cosgi_rulesexecution_python</name>
|
||||
<name>hos_cosgi_ruleengine</name>
|
||||
<version>0.0.0</version>
|
||||
<description>The hos_cosgi_rulesexecution_python package</description>
|
||||
<description>The hos_cosgi_ruleengine package</description>
|
||||
|
||||
<!-- One maintainer tag required, multiple allowed, one person per tag -->
|
||||
<!-- Example: -->
|
||||
@@ -19,7 +19,7 @@
|
||||
<!-- Url tags are optional, but mutiple are allowed, one per tag -->
|
||||
<!-- Optional attribute type can be: website, bugtracker, or repository -->
|
||||
<!-- Example: -->
|
||||
<!-- <url type="website">http://wiki.ros.org/hos_cosgi_rulesexecution_python</url> -->
|
||||
<!-- <url type="website">http://wiki.ros.org/hos_cosgi_ruleengine</url> -->
|
||||
|
||||
|
||||
<!-- Author tags are optional, mutiple are allowed, one per tag -->
|
||||
@@ -42,16 +42,22 @@
|
||||
<buildtool_depend>catkin</buildtool_depend>
|
||||
<build_depend>hos_celix</build_depend>
|
||||
<build_depend>hos_cosgi_common</build_depend>
|
||||
<build_depend>hos_cosgi_devicerepository</build_depend>
|
||||
<build_depend>hos_cosgi_launcher</build_depend>
|
||||
<build_depend>hos_cosgi_rulesengine</build_depend>
|
||||
<build_depend>hos_cosgi_scripting</build_depend>
|
||||
<build_depend>hos_cpp_common</build_depend>
|
||||
<build_depend>hos_libvariant</build_depend>
|
||||
<build_depend>roscpp</build_depend>
|
||||
<build_depend>hos_cpp_cron</build_depend>
|
||||
<run_depend>hos_celix</run_depend>
|
||||
<run_depend>hos_cosgi_common</run_depend>
|
||||
<run_depend>hos_cosgi_devicerepository</run_depend>
|
||||
<run_depend>hos_cosgi_launcher</run_depend>
|
||||
<run_depend>hos_cosgi_rulesengine</run_depend>
|
||||
<run_depend>hos_cpp_common</run_depend>
|
||||
<run_depend>hos_libvariant</run_depend>
|
||||
<run_depend>roscpp</run_depend>
|
||||
<run_depend>hos_cpp_cron</run_depend>
|
||||
<run_depend>hos_cosgi_scripting</run_depend>
|
||||
|
||||
|
||||
<!-- The export tag contains other, unspecified, tags -->
|
||||
+34
-37
@@ -13,28 +13,28 @@
|
||||
#include "ros/ros.h"
|
||||
|
||||
extern "C" {
|
||||
#include "hos_celix/bundle_activator.h"
|
||||
#include "hos_celix/bundle_context.h"
|
||||
#include "hos_celix/service_listener.h"
|
||||
#include "hos_celix/service_reference.h"
|
||||
#include "hos_celix/constants.h"
|
||||
#include "celix/bundle_activator.h"
|
||||
#include "celix/bundle_context.h"
|
||||
#include "celix/service_listener.h"
|
||||
#include "celix/service_reference.h"
|
||||
#include "celix/constants.h"
|
||||
}
|
||||
|
||||
#include <hos_cosgi_launcher/hos_core_service.h>
|
||||
#include "hos_rulesengine_service_impl.h"
|
||||
#include <hos/cosgi/service/core/core_service.h>
|
||||
#include "hos/cosgi/service/ruleengine/ruleengine_serviceimpl.h"
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
|
||||
using namespace hos::cosgi::rulesengine;
|
||||
using namespace hos::cosgi::rulesexecution;
|
||||
using namespace hos::cosgi::devicerepository;
|
||||
using namespace hos::cosgi::core;
|
||||
using namespace hos::cosgi::service::ruleengine;
|
||||
using namespace hos::cosgi::service::scripting;
|
||||
using namespace hos::cosgi::service::devicerepository;
|
||||
using namespace hos::cosgi::service::core;
|
||||
using namespace hos::cosgi;
|
||||
|
||||
struct UserData {
|
||||
apr_pool_t* memoryPool = nullptr;
|
||||
std::unique_ptr<HOSRulesEngineServiceImpl> serviceImpl = nullptr;
|
||||
std::unique_ptr<RuleEngineServiceImpl> serviceImpl = nullptr;
|
||||
service_registration_pt serviceReg = nullptr;
|
||||
serviceListener myServiceListener;
|
||||
bundle_context_pt bundleContext;
|
||||
@@ -47,20 +47,20 @@ celix_status_t cb_serviceChanged(void* listener, service_event_pt event) {
|
||||
char* serviceName = nullptr;
|
||||
bool checkReg = false;
|
||||
serviceReference_getProperty(event->reference, (char*)OSGI_FRAMEWORK_OBJECTCLASS, &serviceName);
|
||||
if (serviceName && std::strcmp(serviceName, HOSDeviceRepositoryService::SERVICE_NAME) == 0) {
|
||||
HOSDeviceRepositoryService *service = nullptr;
|
||||
if (serviceName && std::strcmp(serviceName, DeviceRepositoryService::SERVICE_NAME) == 0) {
|
||||
DeviceRepositoryService *service = nullptr;
|
||||
bundleContext_getService(myUserData->bundleContext, event->reference, (void**)&service);
|
||||
myUserData->serviceImpl->setRepoService(service);
|
||||
checkReg = true;
|
||||
} else if (serviceName && std::strcmp(serviceName, HOSRulesExecutionService::SERVICE_NAME) == 0) {
|
||||
HOSRulesExecutionService *service = nullptr;
|
||||
} else if (serviceName && std::strcmp(serviceName, ScriptingService::SERVICE_NAME) == 0) {
|
||||
ScriptingService *service = nullptr;
|
||||
bundleContext_getService(myUserData->bundleContext, event->reference, (void**)&service);
|
||||
myUserData->serviceImpl->addExecutionBackend(service);
|
||||
checkReg = true;
|
||||
}
|
||||
// Register hos-devicerepository-service
|
||||
if (checkReg && !myUserData->serviceReg && myUserData->serviceImpl->isInitialized()) {
|
||||
bundleContext_registerService(myUserData->bundleContext, (char*)HOSRulesEngineServiceImpl::SERVICE_NAME, myUserData->serviceImpl.get(), nullptr, &myUserData->serviceReg);
|
||||
bundleContext_registerService(myUserData->bundleContext, (char*)RuleEngineServiceImpl::SERVICE_NAME, myUserData->serviceImpl.get(), nullptr, &myUserData->serviceReg);
|
||||
}
|
||||
} else if (event->type == OSGI_FRAMEWORK_SERVICE_EVENT_UNREGISTERING) {
|
||||
}
|
||||
@@ -73,7 +73,7 @@ celix_status_t bundleActivator_create(bundle_context_pt context, void **userData
|
||||
// Create APR memory pool
|
||||
apr_status_t astatus = apr_pool_create(&memoryPool, NULL);
|
||||
if (astatus != APR_SUCCESS) {
|
||||
ROS_ERROR("RulesEngineService: Could not create APR memory pool (%i).", astatus);
|
||||
ROS_ERROR("RuleEngineService: Could not create APR memory pool (%i).", astatus);
|
||||
} else {
|
||||
// Create user data
|
||||
UserData* myUserData = (UserData*)apr_palloc(memoryPool, sizeof(UserData));
|
||||
@@ -82,9 +82,9 @@ celix_status_t bundleActivator_create(bundle_context_pt context, void **userData
|
||||
myUserData->bundleContext = context;
|
||||
*userData = (void*)myUserData;
|
||||
status = CELIX_SUCCESS;
|
||||
ROS_INFO("RulesEngineService: Bundle successfully created");
|
||||
ROS_INFO("RuleEngineService: Bundle successfully created");
|
||||
} else {
|
||||
ROS_ERROR("RulesEngineService: Could not create user data struct");
|
||||
ROS_ERROR("RuleEngineService: Could not create user data struct");
|
||||
apr_pool_destroy(memoryPool);
|
||||
}
|
||||
}
|
||||
@@ -100,39 +100,36 @@ celix_status_t bundleActivator_start(void * userData, bundle_context_pt context)
|
||||
serviceRegistration_unregister(myUserData->serviceReg);
|
||||
myUserData->serviceReg = nullptr;
|
||||
}
|
||||
myUserData->serviceImpl.reset(new HOSRulesEngineServiceImpl());
|
||||
myUserData->serviceImpl.reset(new RuleEngineServiceImpl());
|
||||
// Get HOS Core Service
|
||||
service_reference_pt ref = nullptr;
|
||||
bundleContext_getServiceReference(context, (char*)HOSCoreService::SERVICE_NAME, &ref);
|
||||
HOSCoreService* coreService = nullptr;
|
||||
bundleContext_getServiceReference(context, (char*)CoreService::SERVICE_NAME, &ref);
|
||||
CoreService* coreService = nullptr;
|
||||
bundleContext_getService(context, ref, (void**)&coreService);
|
||||
if (coreService == nullptr) {
|
||||
ROS_ERROR("RulesEngineService: Could not retrieve HOSCoreService. Are you using hos_cosgi_launcher?");
|
||||
ROS_ERROR("RuleEngineService: Could not retrieve HOSCoreService. Are you using hos_cosgi_launcher?");
|
||||
} else {
|
||||
myUserData->serviceImpl->setCoreService(coreService);
|
||||
}
|
||||
// Get HOS Core Service
|
||||
service_reference_pt ref2 = nullptr;
|
||||
bundleContext_getServiceReference(context, (char*)HOSDeviceRepositoryService::SERVICE_NAME, &ref2);
|
||||
HOSDeviceRepositoryService* repoService = nullptr;
|
||||
bundleContext_getServiceReference(context, (char*)DeviceRepositoryService::SERVICE_NAME, &ref2);
|
||||
DeviceRepositoryService* repoService = nullptr;
|
||||
bundleContext_getService(context, ref2, (void**)&repoService);
|
||||
if (repoService) {
|
||||
myUserData->serviceImpl->setRepoService(repoService);
|
||||
}
|
||||
// Register hos-devicerepository-service
|
||||
if (myUserData->serviceImpl->isInitialized()) {
|
||||
bundleContext_registerService(context, (char*)HOSRulesEngineServiceImpl::SERVICE_NAME, myUserData->serviceImpl.get(), nullptr, &myUserData->serviceReg);
|
||||
bundleContext_registerService(context, (char*)RuleEngineServiceImpl::SERVICE_NAME, myUserData->serviceImpl.get(), nullptr, &myUserData->serviceReg);
|
||||
}
|
||||
// Register service listener
|
||||
myUserData->myServiceListener.handle = myUserData;
|
||||
myUserData->myServiceListener.serviceChanged = cb_serviceChanged;
|
||||
char filter[256];
|
||||
std::snprintf(filter, 256, "(objectClass=%s|objectClass=%s)", HOSDeviceRepositoryService::SERVICE_NAME, HOSRulesExecutionService::SERVICE_NAME);
|
||||
//bundleContext_addServiceListener(context, &myUserData->myServiceListener, filter);
|
||||
bundleContext_addServiceListener(context, &myUserData->myServiceListener, nullptr);
|
||||
ROS_INFO("RulesEngineService: Bundle successfully started");
|
||||
ROS_INFO("RuleEngineService: Bundle successfully started");
|
||||
} else {
|
||||
ROS_ERROR("RulesEngineService: Could not start bundle, user data struct is null");
|
||||
ROS_ERROR("RuleEngineService: Could not start bundle, user data struct is null");
|
||||
}
|
||||
return status;
|
||||
}
|
||||
@@ -149,10 +146,10 @@ celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context)
|
||||
if (myUserData->serviceImpl) {
|
||||
myUserData->serviceImpl.reset();
|
||||
}
|
||||
ROS_INFO("RulesEngineService: Bundle successfully stopped");
|
||||
ROS_INFO("RuleEngineService: Bundle successfully stopped");
|
||||
status = CELIX_SUCCESS;
|
||||
} else {
|
||||
ROS_ERROR("RulesEngineService: Could not stop bundle, user data struct is null");
|
||||
ROS_ERROR("RuleEngineService: Could not stop bundle, user data struct is null");
|
||||
}
|
||||
return status;
|
||||
}
|
||||
@@ -163,13 +160,13 @@ celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt contex
|
||||
apr_pool_t* memoryPool = ((UserData*)userData)->memoryPool;
|
||||
if (memoryPool != nullptr) {
|
||||
apr_pool_destroy(memoryPool);
|
||||
ROS_INFO("RulesEngineService: Bundle successfully destroyed");
|
||||
ROS_INFO("RuleEngineService: Bundle successfully destroyed");
|
||||
} else {
|
||||
ROS_ERROR("RulesEngineService: Could not destroy bundle, there is no APR memory pool");
|
||||
ROS_ERROR("RuleEngineService: Could not destroy bundle, there is no APR memory pool");
|
||||
}
|
||||
status = CELIX_SUCCESS;
|
||||
} else {
|
||||
ROS_ERROR("RulesEngineService: Could not destroy bundle, user data struct is null");
|
||||
ROS_ERROR("RuleEngineService: Could not destroy bundle, user data struct is null");
|
||||
}
|
||||
return status;
|
||||
}
|
||||
+13
-7
@@ -7,22 +7,26 @@
|
||||
|
||||
|
||||
#include "Rule.h"
|
||||
|
||||
#include <hos/cosgi/service/scripting/scripting_service.h>
|
||||
|
||||
#include "RuleCondition.h"
|
||||
#include <hos_cosgi_rulesengine/hos_rulesexecution_service.h>
|
||||
#include <ros/ros.h>
|
||||
|
||||
|
||||
namespace hos {
|
||||
namespace cosgi {
|
||||
namespace rulesengine {
|
||||
namespace service {
|
||||
namespace ruleengine {
|
||||
namespace rule {
|
||||
|
||||
|
||||
Rule::Rule(RulePackage* parent, std::string name, rulesexecution::HOSRulesExecutionService* executionService)
|
||||
Rule::Rule(RulePackage* parent, std::string name, scripting::ScriptingService* executionService)
|
||||
: parent(parent), name(name), executionService(executionService) {}
|
||||
|
||||
Rule::~Rule() {}
|
||||
|
||||
std::shared_ptr<Rule> Rule::createRule(RulePackage* parent, std::string name, rulesexecution::GlobalExecutionContext* gContext, libvariant::Variant raw, rulesexecution::HOSRulesExecutionService* executionService) {
|
||||
std::shared_ptr<Rule> Rule::createRule(RulePackage* parent, std::string name, scripting::GlobalScriptContext* gContext, Variant raw, scripting::ScriptingService* executionService) {
|
||||
std::shared_ptr<Rule> retval;
|
||||
if (raw.IsMap()) {
|
||||
retval = std::make_shared<Rule>(parent, name, executionService);
|
||||
@@ -33,7 +37,7 @@ std::shared_ptr<Rule> Rule::createRule(RulePackage* parent, std::string name, ru
|
||||
retval->conditions.push_back(cond);
|
||||
}
|
||||
if (raw.HasPath("body") && raw["body"].IsMap()) {
|
||||
retval->body = executionService->createRuleBody(retval.get(), gContext, raw["body"]);
|
||||
retval->body = executionService->createScript(gContext, raw["body"]);
|
||||
} else {
|
||||
ROS_ERROR_STREAM("Could not create rule \"" << name << "\".");
|
||||
retval.reset();
|
||||
@@ -46,11 +50,13 @@ std::shared_ptr<Rule> Rule::createRule(RulePackage* parent, std::string name, ru
|
||||
return retval;
|
||||
}
|
||||
|
||||
void Rule::exec(rulesexecution::GlobalExecutionContext* gContext) {
|
||||
void Rule::exec(scripting::GlobalScriptContext* gContext) {
|
||||
body->exec(gContext);
|
||||
}
|
||||
|
||||
|
||||
} /* namespace rulesengine */
|
||||
} /* namespace rule */
|
||||
} /* namespace ruleengine */
|
||||
} /* namespace service */
|
||||
} /* namespace cosgi */
|
||||
} /* namespace hos */
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Rule.h
|
||||
*
|
||||
* Created on: 29.04.2015
|
||||
* Author: matzman
|
||||
*/
|
||||
|
||||
#ifndef SRC_HOS_COSGI_SERVICE_RULEENGINE_RULE_RULE_H_
|
||||
#define SRC_HOS_COSGI_SERVICE_RULEENGINE_RULE_RULE_H_
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <Variant/Variant.h>
|
||||
|
||||
|
||||
// Forward declarations
|
||||
namespace hos {
|
||||
namespace cosgi {
|
||||
namespace service {
|
||||
namespace ruleengine {
|
||||
namespace rule {
|
||||
class RulePackage;
|
||||
class RuleCondition;
|
||||
}
|
||||
}
|
||||
namespace scripting {
|
||||
class ScriptingService;
|
||||
class GlobalScriptContext;
|
||||
class Script;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace hos {
|
||||
namespace cosgi {
|
||||
namespace service {
|
||||
namespace ruleengine {
|
||||
namespace rule {
|
||||
|
||||
using namespace libvariant;
|
||||
|
||||
class Rule {
|
||||
private:
|
||||
RulePackage* parent;
|
||||
std::string name;
|
||||
std::shared_ptr<scripting::Script> body;
|
||||
std::vector<std::shared_ptr<RuleCondition>> conditions;
|
||||
scripting::ScriptingService* executionService;
|
||||
public:
|
||||
Rule(RulePackage* parent, std::string name, scripting::ScriptingService* executionService);
|
||||
static std::shared_ptr<Rule> createRule(RulePackage* parent, std::string name, scripting::GlobalScriptContext* gContext, Variant raw, scripting::ScriptingService* executionService);
|
||||
virtual ~Rule();
|
||||
|
||||
RulePackage* getParent() { return parent; }
|
||||
|
||||
virtual void exec(scripting::GlobalScriptContext* gContext);
|
||||
};
|
||||
|
||||
class RuleBody {
|
||||
|
||||
};
|
||||
|
||||
|
||||
} /* namespace rule */
|
||||
} /* namespace ruleengine */
|
||||
} /* namespace service */
|
||||
} /* namespace cosgi */
|
||||
} /* namespace hos */
|
||||
|
||||
|
||||
#endif /* SRC_HOS_COSGI_SERVICE_RULEENGINE_RULE_RULE_H_ */
|
||||
+7
-3
@@ -9,15 +9,19 @@
|
||||
|
||||
namespace hos {
|
||||
namespace cosgi {
|
||||
namespace rulesengine {
|
||||
namespace service {
|
||||
namespace ruleengine {
|
||||
namespace rule {
|
||||
|
||||
|
||||
std::shared_ptr<RuleCondition> RuleCondition::createRuleCondition(Rule* parent, libvariant::Variant raw) {
|
||||
std::shared_ptr<RuleCondition> RuleCondition::createRuleCondition(Rule* parent, Variant raw) {
|
||||
std::shared_ptr<RuleCondition> retval;
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
} /* namespace rulesengine */
|
||||
} /* namespace rule */
|
||||
} /* namespace ruleengine */
|
||||
} /* namespace service */
|
||||
} /* namespace cosgi */
|
||||
} /* namespace hos */
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* RuleCondition.h
|
||||
*
|
||||
* Created on: 29.04.2015
|
||||
* Author: matzman
|
||||
*/
|
||||
|
||||
#ifndef SRC_HOS_COSGI_SERVICE_RULEENGINE_RULE_RULECONDITION_H_
|
||||
#define SRC_HOS_COSGI_SERVICE_RULEENGINE_RULE_RULECONDITION_H_
|
||||
|
||||
#include <memory>
|
||||
#include <Variant/Variant.h>
|
||||
#include <hos/common/observable.h>
|
||||
|
||||
|
||||
// Forward declarations
|
||||
namespace hos {
|
||||
namespace cosgi {
|
||||
namespace service {
|
||||
namespace ruleengine {
|
||||
namespace rule {
|
||||
class Rule;
|
||||
class ConditionDeviceStatusMsgEvent;
|
||||
class ConditionDeviceCommandMsgEvent;
|
||||
class ConditionDeviceStateChangedEvent;
|
||||
class ConditionSystemEvent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace hos {
|
||||
namespace cosgi {
|
||||
namespace service {
|
||||
namespace ruleengine {
|
||||
namespace rule {
|
||||
|
||||
using namespace libvariant;
|
||||
|
||||
class RuleCondition {
|
||||
public:
|
||||
enum class Type : int { DeviceStatusMsg, DeviceCommandMsg, DeviceStateChange, TimeEventCondition, SystemEventCondition};
|
||||
protected:
|
||||
Rule* parent;
|
||||
const Type type;
|
||||
public:
|
||||
static std::shared_ptr<RuleCondition> createRuleCondition(Rule* parent, libvariant::Variant raw);
|
||||
RuleCondition(Rule* parent, Type type) : parent(parent), type(type) {}
|
||||
public:
|
||||
virtual ~RuleCondition() {}
|
||||
|
||||
const Type getType() { return type; }
|
||||
};
|
||||
|
||||
|
||||
class DeviceMsgCondition : public RuleCondition {
|
||||
friend class RuleCondition;
|
||||
protected:
|
||||
Variant msgValue;
|
||||
std::string msgPath;
|
||||
std::string deviceID;
|
||||
DeviceMsgCondition(Rule* parent, Type type, const Variant msgValue, const std::string msgPath, std::string deviceID)
|
||||
: RuleCondition(parent, type) {}
|
||||
};
|
||||
|
||||
|
||||
class DeviceStatusMsgCondition : public DeviceMsgCondition, public common::IObserver<std::string, ConditionDeviceStatusMsgEvent> {
|
||||
friend class RuleCondition;
|
||||
protected:
|
||||
DeviceStatusMsgCondition(Rule* parent, const Variant msgValue, const std::string msgPath, std::string deviceID)
|
||||
: DeviceMsgCondition(parent, Type::DeviceStatusMsg, msgValue, msgPath, deviceID) {}
|
||||
public:
|
||||
virtual void notificationReceived(common::Observable<std::string, ConditionDeviceStatusMsgEvent>* o, const std::string key, const ConditionDeviceStatusMsgEvent* e) override;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class DeviceCommandMsgCondition : public DeviceMsgCondition, public common::IObserver<std::string, ConditionDeviceCommandMsgEvent> {
|
||||
friend class RuleCondition;
|
||||
protected:
|
||||
public:
|
||||
DeviceCommandMsgCondition(Rule* parent, const Variant msgValue, const std::string msgPath, std::string deviceID)
|
||||
: DeviceMsgCondition(parent, Type::DeviceCommandMsg, msgValue, msgPath, deviceID) {}
|
||||
virtual void notificationReceived(common::Observable<std::string, ConditionDeviceCommandMsgEvent>* o, const std::string key, const ConditionDeviceCommandMsgEvent* e) override;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class DeviceStateChangeCondition : public RuleCondition, public common::IObserver<std::string, ConditionDeviceStateChangedEvent> {
|
||||
friend class RuleCondition;
|
||||
protected:
|
||||
public:
|
||||
DeviceStateChangeCondition(Rule* parent) : RuleCondition(parent, Type::DeviceStateChange) {}
|
||||
virtual void notificationReceived(common::Observable<std::string, ConditionDeviceStateChangedEvent>* o, const std::string key, const ConditionDeviceStateChangedEvent* e) override;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class TimeEventCondition : public RuleCondition {
|
||||
friend class RuleCondition;
|
||||
protected:
|
||||
public:
|
||||
TimeEventCondition(Rule* parent) : RuleCondition(parent, Type::TimeEventCondition) {}
|
||||
};
|
||||
|
||||
|
||||
|
||||
class SystemEventCondition : public RuleCondition, public common::IObserver<std::string, ConditionSystemEvent> {
|
||||
friend class RuleCondition;
|
||||
protected:
|
||||
public:
|
||||
SystemEventCondition(Rule* parent) : RuleCondition(parent, Type::SystemEventCondition) {}
|
||||
virtual void notificationReceived(common::Observable<std::string, ConditionSystemEvent>* o, const std::string key, const ConditionSystemEvent* e) override;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace rule */
|
||||
} /* namespace ruleengine */
|
||||
} /* namespace service */
|
||||
} /* namespace cosgi */
|
||||
} /* namespace hos */
|
||||
|
||||
#endif /* SRC_HOS_COSGI_SERVICE_RULEENGINE_RULE_RULECONDITION_H_ */
|
||||
+13
-7
@@ -6,23 +6,27 @@
|
||||
*/
|
||||
|
||||
#include "RulePackage.h"
|
||||
#include "Rule.h"
|
||||
|
||||
#include <ros/ros.h>
|
||||
#include <exception>
|
||||
#include <Variant/Variant.h>
|
||||
#include "../hos_rulesengine_service_impl.h"
|
||||
|
||||
#include "../ruleengine_serviceimpl.h"
|
||||
#include "Rule.h"
|
||||
|
||||
namespace hos {
|
||||
namespace cosgi {
|
||||
namespace rulesengine {
|
||||
namespace service {
|
||||
namespace ruleengine {
|
||||
namespace rule {
|
||||
|
||||
RulePackage::RulePackage(HOSRulesEngineServiceImpl* parent, std::string name)
|
||||
RulePackage::RulePackage(service::ruleengine::RuleEngineServiceImpl* parent, std::string name)
|
||||
: parent(parent), name(name) {}
|
||||
|
||||
RulePackage::~RulePackage() {
|
||||
}
|
||||
|
||||
std::shared_ptr<RulePackage> RulePackage::createRulePackage(HOSRulesEngineServiceImpl* parent, std::string name, ::libvariant::Variant raw) {
|
||||
std::shared_ptr<RulePackage> RulePackage::createRulePackage(service::ruleengine::RuleEngineServiceImpl* parent, std::string name, Variant raw) {
|
||||
std::shared_ptr<RulePackage> retval;
|
||||
if (raw.IsMap()) {
|
||||
retval = std::make_shared<RulePackage>(parent, name);
|
||||
@@ -34,7 +38,7 @@ std::shared_ptr<RulePackage> RulePackage::createRulePackage(HOSRulesEngineServic
|
||||
retval->executionService = parent->getExecutionBackend(retval->language);
|
||||
if (retval->executionService) {
|
||||
if (raw.HasPath("globalcontext")) {
|
||||
retval->globalContext = retval->executionService->createGlobalExecutionContext(retval.get(), raw["globalcontext"]);
|
||||
retval->globalContext = retval->executionService->createGlobalScriptContext(raw["globalcontext"]);
|
||||
}
|
||||
if (raw.HasPath("rules") && raw["rules"].IsMap()) {
|
||||
for (auto r : raw["rules"].AsMap()) {
|
||||
@@ -68,6 +72,8 @@ size_t RulePackage::getRules(std::vector<std::shared_ptr<Rule>>& rules) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
} /* namespace rulesengine */
|
||||
} /* namespace rule */
|
||||
} /* namespace ruleengine */
|
||||
} /* namespace service */
|
||||
} /* namespace cosgi */
|
||||
} /* namespace hos */
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* RulePackage.h
|
||||
*
|
||||
* Created on: 29.04.2015
|
||||
* Author: matzman
|
||||
*/
|
||||
|
||||
#ifndef SRC_HOS_COSGI_SERVICE_RULEENGINE_RULE_RULEPACKAGE_H_
|
||||
#define SRC_HOS_COSGI_SERVICE_RULEENGINE_RULE_RULEPACKAGE_H_
|
||||
|
||||
|
||||
#include <hos/cosgi/service/scripting/scripting_service.h>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <Variant/Variant.h>
|
||||
|
||||
|
||||
// Forward declarations
|
||||
namespace hos {
|
||||
namespace cosgi {
|
||||
namespace service {
|
||||
namespace ruleengine {
|
||||
class RuleEngineServiceImpl;
|
||||
namespace rule {
|
||||
class Rule;
|
||||
}
|
||||
}
|
||||
namespace scripting {
|
||||
class GlobalScriptContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace hos {
|
||||
namespace cosgi {
|
||||
namespace service {
|
||||
namespace ruleengine {
|
||||
namespace rule {
|
||||
|
||||
using namespace ::libvariant;
|
||||
|
||||
class RulePackage {
|
||||
public:
|
||||
enum class State : int { Error = 0, NoExecService = 1, Ok = 2 };
|
||||
|
||||
private:
|
||||
typedef std::map<std::string, std::shared_ptr<Rule>> ruleMap_t;
|
||||
|
||||
std::string name;
|
||||
std::string language;
|
||||
State state = State::Error;
|
||||
ruleMap_t rules;
|
||||
std::shared_ptr<scripting::GlobalScriptContext> globalContext;
|
||||
service::ruleengine::RuleEngineServiceImpl* parent;
|
||||
service::scripting::ScriptingService* executionService = nullptr;
|
||||
|
||||
|
||||
bool setState(State state) {
|
||||
this->state = state;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
RulePackage(service::ruleengine::RuleEngineServiceImpl* parent, std::string name);
|
||||
static std::shared_ptr<RulePackage> createRulePackage(service::ruleengine::RuleEngineServiceImpl* parent, std::string name, Variant raw);
|
||||
virtual ~RulePackage();
|
||||
|
||||
std::shared_ptr<Rule> getRule(const std::string& name) { return rules[name]; }
|
||||
size_t getRules(std::vector<std::shared_ptr<Rule>>& rules);
|
||||
|
||||
service::ruleengine::RuleEngineServiceImpl* getParent() { return parent; }
|
||||
|
||||
State getState() { return state; }
|
||||
};
|
||||
|
||||
} /* namespace rule */
|
||||
} /* namespace ruleengine */
|
||||
} /* namespace service */
|
||||
} /* namespace cosgi */
|
||||
} /* namespace hos */
|
||||
|
||||
#endif /* SRC_HOS_COSGI_SERVICE_RULEENGINE_RULE_RULEPACKAGE_H_ */
|
||||
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* hos_ruleengine_service_impl.cpp
|
||||
*
|
||||
* Created on: 26.04.2015
|
||||
* Author: matzman
|
||||
*/
|
||||
|
||||
#include "ruleengine_serviceimpl.h"
|
||||
#include <ros/ros.h>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <unordered_set>
|
||||
#include <celix/bundle_context.h>
|
||||
#include <hos/cosgi/service/core/core_service.h>
|
||||
#include <hos/cosgi/service/devicerepository/devicerepository_service.h>
|
||||
#include <Variant/Variant.h>
|
||||
|
||||
#include "rule/RulePackage.h"
|
||||
|
||||
|
||||
namespace hos {
|
||||
namespace cosgi {
|
||||
namespace service {
|
||||
namespace ruleengine {
|
||||
|
||||
template<> const char* implementation::ServiceInfo<RuleEngineServiceImpl>::name = service::ruleengine::RuleEngineService::SERVICE_NAME;
|
||||
template<> const int implementation::ServiceInfo<RuleEngineServiceImpl>::major = 0;
|
||||
template<> const int implementation::ServiceInfo<RuleEngineServiceImpl>::minor = 6;
|
||||
|
||||
void RuleEngineServiceImpl::setCoreService(service::core::CoreService* coreService) {
|
||||
if (coreService && !this->coreService) {
|
||||
this->coreService = coreService;
|
||||
this->nodehandle = coreService->getPrivateNodeHandle();
|
||||
int major = 0, minor = 0;
|
||||
coreService->getServiceVersion(major, minor);
|
||||
ROS_INFO_STREAM("RuleEngineService: Found HOSCoreService Version " << major << "." << minor);
|
||||
if (repoService) {
|
||||
init();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RuleEngineServiceImpl::setRepoService(devicerepository::DeviceRepositoryService* repoService) {
|
||||
if (repoService && !this->repoService) {
|
||||
this->repoService = repoService;
|
||||
int major = 0, minor = 0;
|
||||
repoService->getServiceVersion(major, minor);
|
||||
ROS_INFO_STREAM("RuleEngineService: Found HOSDeviceRepositoryService Version " << major << "." << minor);
|
||||
if (coreService) {
|
||||
init();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RuleEngineServiceImpl::init() {
|
||||
nodehandle->getParam("ruleengine_prefix", ruleEnginePrefix);
|
||||
XmlRpc::XmlRpcValue rawValue;
|
||||
nodehandle->getParam(ruleEnginePrefix, rawValue);
|
||||
schemaLoader.reset(new libvariant::HosSchemaLoader());
|
||||
if (rawValue.getType() == XmlRpc::XmlRpcValue::TypeStruct) {
|
||||
for (auto pkg : rawValue) {
|
||||
std::string pname = pkg.first;
|
||||
XmlRpc::XmlRpcValue pRaw = pkg.second;
|
||||
try {
|
||||
addRulePkg(pname, pRaw);
|
||||
ROS_INFO_STREAM("Created rule package " << pname << ".");
|
||||
} catch (std::exception& e) {
|
||||
ROS_ERROR_STREAM("Could not create rule package " << pname << ": " << e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
repoService->addObserver(this);
|
||||
initialized = true;
|
||||
ROS_INFO_STREAM("RuleEngineService: Initialized and Ready.");
|
||||
}
|
||||
|
||||
RuleEngineServiceImpl::~RuleEngineServiceImpl() {
|
||||
repoService->deleteObserver(this);
|
||||
}
|
||||
|
||||
|
||||
void RuleEngineServiceImpl::notificationReceived(interface::Observer<devicerepository::DeviceEvent>::observable_type* o, const devicerepository::DeviceEvent* e) {
|
||||
switch (e->eventType) {
|
||||
case devicerepository::DeviceEvent::EventType::STATUS_UPDATED:
|
||||
{
|
||||
ConditionDeviceStatusMsgEvent event;
|
||||
common::Observable<std::string, ConditionDeviceStatusMsgEvent>::notifyObservers(e->device->getDeviceID(), &event);
|
||||
if (e->device->stateChanged()) {
|
||||
ConditionDeviceStateChangedEvent event;
|
||||
common::Observable<std::string, ConditionDeviceStateChangedEvent>::notifyObservers(e->device->getDeviceID(), &event);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case devicerepository::DeviceEvent::EventType::COMMAND_RECEIVED:
|
||||
{
|
||||
ConditionDeviceCommandMsgEvent event;
|
||||
common::Observable<std::string, ConditionDeviceCommandMsgEvent>::notifyObservers(e->device->getDeviceID(), &event);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void RuleEngineServiceImpl::addRulePkg(std::string name) {
|
||||
std::stringstream ss;
|
||||
ss << ruleEnginePrefix << "/" << name;
|
||||
XmlRpc::XmlRpcValue rawValue;
|
||||
nodehandle->getParam(ss.str(), rawValue);
|
||||
addRulePkg(name, static_cast<std::string>(rawValue));
|
||||
}
|
||||
|
||||
void RuleEngineServiceImpl::addRulePkg(std::string name, std::string rawValue) {
|
||||
::libvariant::Variant s = schemaLoader->GetSchema(std::string("hos:schema://core/configs/rulepackage"));
|
||||
::libvariant::Variant m = ::libvariant::Deserialize(rawValue, ::libvariant::SERIALIZE_JSON);
|
||||
::libvariant::SchemaResult sr = ::libvariant::SchemaValidate(s, m, schemaLoader.get());
|
||||
if (!sr.Error()) {
|
||||
std::shared_ptr<rule::RulePackage> pkg = rule::RulePackage::createRulePackage(this, name, m);
|
||||
if (pkg) {
|
||||
if (pkg->getState() == rule::RulePackage::State::Ok) {
|
||||
rulePkgs.insert({name, pkg});
|
||||
} else if (pkg->getState() == rule::RulePackage::State::NoExecService) {
|
||||
noExecRulePkgs.insert({name, pkg});
|
||||
std::cout << "No execution service found for rule package \"" << name << "\"" << std::endl;
|
||||
} else {
|
||||
throw std::runtime_error("Unknown state");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw std::runtime_error(sr.PrettyPrintMessage());
|
||||
}
|
||||
}
|
||||
|
||||
void RuleEngineServiceImpl::removeRulePkg(std::string name) {
|
||||
rulePkgs.erase(name);
|
||||
}
|
||||
|
||||
void RuleEngineServiceImpl::addExecutionBackend(scripting::ScriptingService* service) {
|
||||
if (execServices.find(service->getLanguage()) == execServices.end()) {
|
||||
execServices.insert({service->getLanguage(), service});
|
||||
ROS_INFO_STREAM("RuleEngineService: Added execution service \"" << service->getLanguage() << "\".");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
scripting::ScriptingService* RuleEngineServiceImpl::getExecutionBackend(std::string language) {
|
||||
auto s = execServices.find(language);
|
||||
if (s != execServices.end()) {
|
||||
return s->second;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
} // namespace ruleengine
|
||||
} // namespace service
|
||||
} // namespace cosgi
|
||||
} // namespace hos
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* hos_ruleengine_service_impl.h
|
||||
*
|
||||
* Created on: 26.04.2015
|
||||
* Author: matzman
|
||||
*/
|
||||
|
||||
#ifndef INCLUDE_HOS_COSGI_RULEENGINE_HOS_RULEENGINE_SERVICE_IMPL_H_
|
||||
#define INCLUDE_HOS_COSGI_RULEENGINE_HOS_RULEENGINE_SERVICE_IMPL_H_
|
||||
|
||||
#include <hos/cosgi/service/implementation.h>
|
||||
#include <Variant/Variant.h>
|
||||
#include <mutex>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <hos_core_msgs/DeviceCommand.h>
|
||||
#include <hos_core_msgs/DeviceStatusUpdate.h>
|
||||
#include <hos_core_msgs/HosStatusUpdate.h>
|
||||
#include <hos/cosgi/service/ruleengine/ruleengine_service.h>
|
||||
#include <hos/cosgi/service/scripting/scripting_service.h>
|
||||
#include <hos/cosgi/service/devicerepository/devicerepository_service.h>
|
||||
#include <HosSchemaLoader/HosSchemaLoader.h>
|
||||
#include <ros/ros.h>
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
|
||||
// Forward declarations
|
||||
namespace XmlRpc {
|
||||
class XmlRpcValue;
|
||||
}
|
||||
namespace hos {
|
||||
namespace cosgi {
|
||||
namespace service {
|
||||
namespace core {
|
||||
class CoreService;
|
||||
}
|
||||
namespace ruleengine {
|
||||
namespace rule {
|
||||
class RulePackage;
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace devicerepository {
|
||||
class DeviceRepositoryService;
|
||||
class DeviceEvent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Service Namespace
|
||||
namespace hos {
|
||||
namespace cosgi {
|
||||
namespace service {
|
||||
namespace ruleengine {
|
||||
|
||||
|
||||
class ConditionDeviceStatusMsgEvent {
|
||||
|
||||
};
|
||||
|
||||
class ConditionDeviceCommandMsgEvent {
|
||||
|
||||
};
|
||||
|
||||
class ConditionDeviceStateChangedEvent {
|
||||
|
||||
};
|
||||
|
||||
class ConditionSystemEvent {
|
||||
|
||||
};
|
||||
|
||||
class RuleEngineServiceImpl;
|
||||
class RuleEngineServiceImpl : public virtual RuleEngineService,
|
||||
public virtual implementation::Service<RuleEngineServiceImpl>,
|
||||
public virtual interface::Observer<devicerepository::DeviceEvent>,
|
||||
public common::Observable<std::string, ConditionDeviceStatusMsgEvent>,
|
||||
public common::Observable<std::string, ConditionDeviceCommandMsgEvent>,
|
||||
public common::Observable<std::string, ConditionDeviceStateChangedEvent>,
|
||||
public common::Observable<std::string, ConditionSystemEvent> {
|
||||
private:
|
||||
typedef std::map<std::string, std::shared_ptr<rule::RulePackage>> rulePkgMap_t;
|
||||
typedef std::map<std::string, scripting::ScriptingService*> execServiceMap_t;
|
||||
|
||||
service::core::CoreService* coreService = nullptr;
|
||||
devicerepository::DeviceRepositoryService* repoService = nullptr;
|
||||
ros::NodeHandle* nodehandle = nullptr;
|
||||
|
||||
std::string ruleEnginePrefix = "/hos/rules/ruleengine0";
|
||||
|
||||
rulePkgMap_t rulePkgs;
|
||||
rulePkgMap_t noExecRulePkgs;
|
||||
execServiceMap_t execServices;
|
||||
|
||||
std::unique_ptr<libvariant::HosSchemaLoader> schemaLoader;
|
||||
|
||||
bool initialized = false;
|
||||
|
||||
void addRulePkg(std::string name);
|
||||
void addRulePkg(std::string name, std::string rawValue);
|
||||
void removeRulePkg(std::string name);
|
||||
|
||||
void init();
|
||||
|
||||
public:
|
||||
~RuleEngineServiceImpl();
|
||||
/* Initialization */
|
||||
|
||||
void setCoreService(service::core::CoreService* coreService);
|
||||
void setRepoService(devicerepository::DeviceRepositoryService* repoService);
|
||||
|
||||
/* Public Service Implementations */
|
||||
|
||||
/* Observer Callbacks */
|
||||
|
||||
virtual void notificationReceived(interface::Observer<devicerepository::DeviceEvent>::observable_type* o, const devicerepository::DeviceEvent* e) override;
|
||||
|
||||
/* Internal Stuff */
|
||||
|
||||
bool isInitialized() { return initialized; }
|
||||
|
||||
void addExecutionBackend(scripting::ScriptingService* service);
|
||||
scripting::ScriptingService* getExecutionBackend(std::string language);
|
||||
};
|
||||
|
||||
|
||||
} // namespace ruleengine
|
||||
} // namespace service
|
||||
} // namespace cosgi
|
||||
} // namespace hos
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* INCLUDE_HOS_COSGI_RULEENGINE_HOS_RULEENGINE_SERVICE_IMPL_H_ */
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* hos_rulesengine_service.h
|
||||
*
|
||||
* Created on: 26.04.2015
|
||||
* Author: matzman
|
||||
*/
|
||||
|
||||
#ifndef INCLUDE_HOS_COSGI_RULESENGINE_HOS_RULESENGINE_SERVICE_H_
|
||||
#define INCLUDE_HOS_COSGI_RULESENGINE_HOS_RULESENGINE_SERVICE_H_
|
||||
|
||||
|
||||
#include <hos_cosgi_common/cosgi_common.h>
|
||||
#include <hos_cpp_common/observable.h>
|
||||
|
||||
|
||||
namespace hos {
|
||||
namespace cosgi {
|
||||
namespace rulesengine {
|
||||
|
||||
|
||||
class RulesEngineEvent;
|
||||
|
||||
|
||||
class HOSRulesEngineService : public COSGI_Service_Interface, public common::IObservable<RulesEngineEvent> {
|
||||
public:
|
||||
static constexpr const char* SERVICE_NAME = "hos_rulesengine_service";
|
||||
static constexpr int SERVICE_VERSION_MAJOR = 1;
|
||||
static constexpr int SERVICE_VERSION_MINOR = 0;
|
||||
};
|
||||
|
||||
|
||||
} // namespace rulesengine
|
||||
} // namespace cosgi
|
||||
} // namespace hos
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* INCLUDE_HOS_COSGI_RULESENGINE_HOS_RULESENGINE_SERVICE_H_ */
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* hos_rulesexecution_service.h
|
||||
*
|
||||
* Created on: 01.05.2015
|
||||
* Author: matzman
|
||||
*/
|
||||
|
||||
#ifndef INCLUDE_HOS_COSGI_RULESENGINE_HOS_RULESEXECUTION_SERVICE_H_
|
||||
#define INCLUDE_HOS_COSGI_RULESENGINE_HOS_RULESEXECUTION_SERVICE_H_
|
||||
|
||||
|
||||
#include <hos_cosgi_common/cosgi_common.h>
|
||||
#include <memory>
|
||||
#include <Variant/Variant.h>
|
||||
|
||||
|
||||
// Forward declarations
|
||||
namespace hos {
|
||||
namespace cosgi {
|
||||
namespace rulesengine {
|
||||
class RulePackage;
|
||||
class Rule;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace hos {
|
||||
namespace cosgi {
|
||||
namespace rulesexecution {
|
||||
|
||||
|
||||
class GlobalExecutionContext : public COSGI_Object_Interface {
|
||||
|
||||
};
|
||||
|
||||
|
||||
class RuleBody : public COSGI_Object_Interface {
|
||||
public:
|
||||
virtual void exec(GlobalExecutionContext* gContext) = 0;
|
||||
};
|
||||
|
||||
|
||||
class HOSRulesExecutionService : public COSGI_Service_Interface {
|
||||
public:
|
||||
static constexpr const char* SERVICE_NAME = "hos_rulesexecution_service";
|
||||
|
||||
virtual std::string getLanguage() = 0;
|
||||
|
||||
virtual std::shared_ptr<GlobalExecutionContext> createGlobalExecutionContext(rulesengine::RulePackage* parent, libvariant::Variant raw) = 0;
|
||||
virtual std::shared_ptr<RuleBody> createRuleBody(rulesengine::Rule* parent, GlobalExecutionContext* gContext, libvariant::Variant raw) = 0;
|
||||
};
|
||||
|
||||
|
||||
} // namespace rulesengine
|
||||
} // namespace cosgi
|
||||
} // namespace hos
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* INCLUDE_HOS_COSGI_RULESENGINE_HOS_RULESEXECUTION_SERVICE_H_ */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user