diff --git a/amlip_cpp/include/amlip_cpp/node/collaborative_learning/ModelManagerReceiverNode.hpp b/amlip_cpp/include/amlip_cpp/node/collaborative_learning/ModelManagerReceiverNode.hpp index 2beac2bc..2b4d9d15 100644 --- a/amlip_cpp/include/amlip_cpp/node/collaborative_learning/ModelManagerReceiverNode.hpp +++ b/amlip_cpp/include/amlip_cpp/node/collaborative_learning/ModelManagerReceiverNode.hpp @@ -26,8 +26,8 @@ #include #include -#include -#include +#include +#include #include @@ -54,7 +54,7 @@ namespace node { * @brief Object that listens to: * * - new ModelStatisticsDataType messages received from a \c ModelManagerSenderNode and executes a callback. - * - new ModelSolutionDataType messages received from a \c ModelManagerSenderNode and executes a callback. + * - new ModelReplyDataType messages received from a \c ModelManagerSenderNode and executes a callback. * * This class is supposed to be implemented by a User and be given to a \c ModelManagerReceiverNode in order to process * the messages received from other Nodes in the network. @@ -75,12 +75,12 @@ class ModelListener const types::ModelStatisticsDataType statistics) = 0; /** - * @brief Method that will be called with each ModelSolutionDataType message received + * @brief Method that will be called with each ModelReplyDataType message received * - * @param model new ModelSolutionDataType message received. + * @param model new ModelReplyDataType message received. */ virtual bool model_received ( - const types::ModelSolutionDataType model) = 0; + const types::ModelReplyDataType model) = 0; }; /** @@ -101,7 +101,7 @@ class ModelManagerReceiverNode : public ParentNode */ AMLIP_CPP_DllAPI ModelManagerReceiverNode( types::AmlipIdDataType id, - types::ModelDataType& data, + types::ModelRequestDataType& data, uint32_t domain_id); /** @@ -112,7 +112,7 @@ class ModelManagerReceiverNode : public ParentNode */ AMLIP_CPP_DllAPI ModelManagerReceiverNode( types::AmlipIdDataType id, - types::ModelDataType& data); + types::ModelRequestDataType& data); /** * @brief Construct a new ModelManagerReceiverNode Node object. @@ -123,7 +123,7 @@ class ModelManagerReceiverNode : public ParentNode */ AMLIP_CPP_DllAPI ModelManagerReceiverNode( const char* name, - types::ModelDataType& data, + types::ModelRequestDataType& data, uint32_t domain_id); /** @@ -134,7 +134,7 @@ class ModelManagerReceiverNode : public ParentNode */ AMLIP_CPP_DllAPI ModelManagerReceiverNode( const char* name, - types::ModelDataType& data); + types::ModelRequestDataType& data); /** * @brief Destroy the ModelManagerReceiverNode Node object @@ -190,13 +190,16 @@ class ModelManagerReceiverNode : public ParentNode * * This is created from DDS Participant in ParentNode, and its destruction is handled by ParentNode. */ - std::shared_ptr> model_receiver_; + std::shared_ptr> model_receiver_; //! Whether the Node is currently open to receive data or it is stopped. std::atomic running_; //! Data to request to ModelManagerSenderNode. - types::ModelDataType data_; + types::ModelRequestDataType data_; + + //! Maximum wait reply in milliseconds (0 = no wait) + static const uint32_t REPLY_TIMEOUT_; // 2500 }; } /* namespace node */ diff --git a/amlip_cpp/include/amlip_cpp/node/collaborative_learning/ModelManagerSenderNode.hpp b/amlip_cpp/include/amlip_cpp/node/collaborative_learning/ModelManagerSenderNode.hpp index 088d2c4a..958863d0 100644 --- a/amlip_cpp/include/amlip_cpp/node/collaborative_learning/ModelManagerSenderNode.hpp +++ b/amlip_cpp/include/amlip_cpp/node/collaborative_learning/ModelManagerSenderNode.hpp @@ -26,8 +26,8 @@ #include #include -#include -#include +#include +#include #include @@ -53,7 +53,7 @@ namespace node { /** * @brief Object that listens to: * - * - new ModelDataType messages received from a \c ModelManagerReceiverNode and executes a callback. + * - new ModelRequestDataType messages received from a \c ModelManagerReceiverNode and executes a callback. * * This class is supposed to be implemented by a User and be given to a \c ModelManagerSenderNode in order to process * the messages received from other Nodes in the network. @@ -67,12 +67,12 @@ class ModelReplier virtual ~ModelReplier() = default; /** - * @brief Method that will be called with each ModelSolutionDataType message received to calculate an answer. + * @brief Method that will be called with each ModelReplyDataType message received to calculate an answer. * - * @param data new ModelDataType message received. + * @param data new ModelRequestDataType message received. */ - virtual types::ModelSolutionDataType fetch_model ( - const types::ModelDataType data) = 0; + virtual types::ModelReplyDataType fetch_model ( + const types::ModelRequestDataType data) = 0; }; /** @@ -109,34 +109,42 @@ class ModelManagerSenderNode : public ParentNode AMLIP_CPP_DllAPI ~ModelManagerSenderNode(); /** - * @brief This function copies the values in member \c statistics_ and publishes them + * @brief This function copies the values into a ModelStatisticsDataType object and publishes them * - * @param name New value to be copied in member id \c statistics_.name_ - * @param data New value to be copied in member id \c statistics_.data_ - * @param size New value to be copied in member id \c statistics_.data_size_ + * @param name New value to be copied in member \c name_ + * @param data New value to be copied in member \c data_ + * @param size New value to be copied in member \c data_size_ + * @param copy_data */ - void update_statistics( + void publish_statistics( const std::string& name, void* data, - const uint32_t size); + const uint32_t size, + bool copy_data = true); /** - * @brief This function copies the values in member \c statistics_ and publishes them + * @brief This function copies the values into a ModelStatisticsDataType object and publishes them * - * @param name New value to be copied in member id \c statistics_.name_ - * @param data New value to be copied in member id \c statistics_.data_ + * @param name New value to be copied in member \c name_ + * @param data New value to be copied in member \c data_ + * @param copy_data */ - void update_statistics( + void publish_statistics( const std::string& name, - const std::string& data); + const std::vector& data, + bool copy_data = true); /** - * @brief This function gets the value of member \c statistics_ as ModelStatisticsDataType + * @brief This function copies the values into a ModelStatisticsDataType object and publishes them * - * @return Value of member \c statistics_ as ModelStatisticsDataType + * @param name New value to be copied in member \c name_ + * @param data New value to be copied in member \c data_ + * @param copy_data */ - types::ModelStatisticsDataType statistics(); - + void publish_statistics( + const std::string& name, + const std::string& data, + bool copy_data = true); /** * @brief Process model replies @@ -185,13 +193,11 @@ class ModelManagerSenderNode : public ParentNode * * This is created from DDS Participant in ParentNode, and its destruction is handled by ParentNode. */ - std::shared_ptr> model_sender_; + std::shared_ptr> model_sender_; //! Whether the Node is currently open to receive data or it is stopped. std::atomic running_; - //! Statistical data from models. - types::ModelStatisticsDataType statistics_; }; } /* namespace node */ diff --git a/amlip_cpp/include/amlip_cpp/types/model/ModelDataType.hpp b/amlip_cpp/include/amlip_cpp/types/model/ModelReplyDataType.hpp similarity index 76% rename from amlip_cpp/include/amlip_cpp/types/model/ModelDataType.hpp rename to amlip_cpp/include/amlip_cpp/types/model/ModelReplyDataType.hpp index 30de8da6..d031c6b1 100644 --- a/amlip_cpp/include/amlip_cpp/types/model/ModelDataType.hpp +++ b/amlip_cpp/include/amlip_cpp/types/model/ModelReplyDataType.hpp @@ -13,11 +13,11 @@ // limitations under the License. /*! - * @file ModelDataType.hpp + * @file ModelReplyDataType.hpp */ -#ifndef AMLIPCPP__SRC_CPP_TYPES_MODEL_MODELDATATYPE_HPP -#define AMLIPCPP__SRC_CPP_TYPES_MODEL_MODELDATATYPE_HPP +#ifndef AMLIPCPP__SRC_CPP_TYPES_MODEL_MODELREPLYDATATYPE_HPP +#define AMLIPCPP__SRC_CPP_TYPES_MODEL_MODELREPLYDATATYPE_HPP #include #include @@ -28,10 +28,10 @@ namespace eprosima { namespace amlip { namespace types { -using ModelDataType = GenericDataType; +using ModelReplyDataType = GenericDataType; } /* namespace types */ } /* namespace amlip */ } /* namespace eprosima */ -#endif // AMLIPCPP__SRC_CPP_TYPES_MODEL_MODELDATATYPE_HPP +#endif // AMLIPCPP__SRC_CPP_TYPES_MODEL_MODELREPLYDATATYPE_HPP diff --git a/amlip_cpp/include/amlip_cpp/types/model/ModelSolutionDataType.hpp b/amlip_cpp/include/amlip_cpp/types/model/ModelRequestDataType.hpp similarity index 75% rename from amlip_cpp/include/amlip_cpp/types/model/ModelSolutionDataType.hpp rename to amlip_cpp/include/amlip_cpp/types/model/ModelRequestDataType.hpp index 1b58544c..fb2dddc1 100644 --- a/amlip_cpp/include/amlip_cpp/types/model/ModelSolutionDataType.hpp +++ b/amlip_cpp/include/amlip_cpp/types/model/ModelRequestDataType.hpp @@ -13,11 +13,11 @@ // limitations under the License. /*! - * @file ModelSolutionDataType.hpp + * @file ModelRequestDataType.hpp */ -#ifndef AMLIPCPP__SRC_CPP_TYPES_MODEL_MODELSOLUTIONDATATYPE_HPP -#define AMLIPCPP__SRC_CPP_TYPES_MODEL_MODELSOLUTIONDATATYPE_HPP +#ifndef AMLIPCPP__SRC_CPP_TYPES_MODEL_MODELREQUESTDATATYPE_HPP +#define AMLIPCPP__SRC_CPP_TYPES_MODEL_MODELREQUESTDATATYPE_HPP #include #include @@ -28,10 +28,10 @@ namespace eprosima { namespace amlip { namespace types { -using ModelSolutionDataType = GenericDataType; +using ModelRequestDataType = GenericDataType; } /* namespace types */ } /* namespace amlip */ } /* namespace eprosima */ -#endif // AMLIPCPP__SRC_CPP_TYPES_MODEL_MODELSOLUTIONDATATYPE_HPP +#endif // AMLIPCPP__SRC_CPP_TYPES_MODEL_MODELREQUESTDATATYPE_HPP diff --git a/amlip_cpp/include/amlip_cpp/types/model/ModelStatisticsDataType.hpp b/amlip_cpp/include/amlip_cpp/types/model/ModelStatisticsDataType.hpp index b36e4948..095f4388 100644 --- a/amlip_cpp/include/amlip_cpp/types/model/ModelStatisticsDataType.hpp +++ b/amlip_cpp/include/amlip_cpp/types/model/ModelStatisticsDataType.hpp @@ -23,8 +23,8 @@ #include #include -#include #include +#include namespace eprosima { namespace fastcdr { @@ -49,16 +49,53 @@ class ModelStatisticsDataType : public InterfaceDataType /*! * @brief Constructor with name. + * @param name New value to be copied in member id \c name_ */ AMLIP_CPP_DllAPI ModelStatisticsDataType( const std::string& name); /*! * @brief Constructor with name given in char*. + * @param name New value to be copied in member id \c name_ */ AMLIP_CPP_DllAPI ModelStatisticsDataType( const char* name); + /*! + * @brief Constructor with name, data given in void* and data size. + * @param name New value to be copied in member id \c name_ + * @param data New value to be copied in member id \c data_ + * @param size New value to be copied in member id \c data_size_ + * @param copy_data + */ + AMLIP_CPP_DllAPI ModelStatisticsDataType( + const std::string& name, + void* data, + const uint32_t size, + bool copy_data = true); + + /*! + * @brief Constructor with name and data given in std::vector. + * @param name New value to be copied in member id \c name_ + * @param bytes New value to be copied in member id \c data_ + * @param copy_data + */ + AMLIP_CPP_DllAPI ModelStatisticsDataType( + const std::string& name, + const std::vector& bytes, + bool copy_data = true); + + /*! + * @brief Constructor with name and data. + * @param name New value to be copied in member id \c name_ + * @param bytes New value to be copied in member id \c data_ + * @param copy_data + */ + AMLIP_CPP_DllAPI ModelStatisticsDataType( + const std::string& name, + const std::string& bytes, + bool copy_data = true); + /*! * @brief Default destructor. */ @@ -145,27 +182,14 @@ class ModelStatisticsDataType : public InterfaceDataType AMLIP_CPP_DllAPI void* data() const; /*! - * @brief This function copies the value in member \c data_ - * @param bytes New value to be copied in member id \c data_ - */ - AMLIP_CPP_DllAPI void data( - const std::vector& bytes); - - /*! - * @brief This function copies the value in member \c data_ - * @param bytes New value to be copied in member id \c data_ + * @brief Return value of attribute \c data_ in std::string */ - AMLIP_CPP_DllAPI void data( - const std::string& bytes); + AMLIP_CPP_DllAPI std::string to_string() const noexcept; /*! - * @brief This function copies the value in member \c data_ - * @param data New value to be copied in member id \c data_ - * @param size New value to be copied in member id \c data_size_ + * @brief Return value of attribute \c data_ in std::vector */ - AMLIP_CPP_DllAPI void data( - void* data, - const uint32_t size); + AMLIP_CPP_DllAPI std::vector to_vector() const noexcept; /*! * @brief Return value of attribute \c data_size_ @@ -271,7 +295,7 @@ class ModelStatisticsDataType : public InterfaceDataType }; //! \c ModelStatisticsDataType to stream serializator -AMLIP_CPP_DllAPI std::ostream& operator <<( +std::ostream& operator <<( std::ostream& os, const ModelStatisticsDataType& id); diff --git a/amlip_cpp/src/cpp/dds/rpc/RPCClient.hpp b/amlip_cpp/src/cpp/dds/rpc/RPCClient.hpp index 47f508f2..119e7963 100644 --- a/amlip_cpp/src/cpp/dds/rpc/RPCClient.hpp +++ b/amlip_cpp/src/cpp/dds/rpc/RPCClient.hpp @@ -23,8 +23,9 @@ #include #include -#include #include +#include + #include namespace eprosima { @@ -107,6 +108,11 @@ class RPCClient std::string topic_; std::atomic last_task_id_used_; + + template + friend std::ostream& operator <<( + std::ostream&, + const RPCClient& ); }; //! \c RPCClient to stream serializator diff --git a/amlip_cpp/src/cpp/dds/rpc/RPCServer.hpp b/amlip_cpp/src/cpp/dds/rpc/RPCServer.hpp index 9c518fba..2ea458d6 100644 --- a/amlip_cpp/src/cpp/dds/rpc/RPCServer.hpp +++ b/amlip_cpp/src/cpp/dds/rpc/RPCServer.hpp @@ -23,8 +23,9 @@ #include #include -#include #include +#include + #include namespace eprosima { @@ -118,6 +119,11 @@ class RPCServer types::AmlipIdDataType own_id_; std::string topic_; + + template + friend std::ostream& operator <<( + std::ostream& os, + const RPCServer& ); }; //! \c RPCServer to stream serializator diff --git a/amlip_cpp/src/cpp/dds/rpc/impl/RPCClient.ipp b/amlip_cpp/src/cpp/dds/rpc/impl/RPCClient.ipp index 57e42031..c2180d37 100644 --- a/amlip_cpp/src/cpp/dds/rpc/impl/RPCClient.ipp +++ b/amlip_cpp/src/cpp/dds/rpc/impl/RPCClient.ipp @@ -19,6 +19,7 @@ #ifndef AMLIPCPP__SRC_CPP_DDS_RPC_IMPL_RPCCLIENT_IPP #define AMLIPCPP__SRC_CPP_DDS_RPC_IMPL_RPCCLIENT_IPP +#include #include #include @@ -89,11 +90,17 @@ Solution RPCClient::get_reply( if (reason == eprosima::utils::event::AwakeReason::disabled) { - logDebug(AMLIPCPP_DDS_RPCCLIENT, "ModelManager Node " << this << " finished processing data."); + logDebug(AMLIPCPP_DDS_RPCCLIENT, *this << " finished processing data."); // Break thread execution break; } + else if (reason == eprosima::utils::event::AwakeReason::timeout) + { + logDebug(AMLIPCPP_DDS_RPCCLIENT, *this << " finished waiting for data due to timeout."); + throw eprosima::utils::TimeoutException( + STR_ENTRY << *this << " finished waiting for data due to timeout."); + } try { diff --git a/amlip_cpp/src/cpp/dds/rpc/impl/RPCServer.ipp b/amlip_cpp/src/cpp/dds/rpc/impl/RPCServer.ipp index d06e3b97..e7f07451 100644 --- a/amlip_cpp/src/cpp/dds/rpc/impl/RPCServer.ipp +++ b/amlip_cpp/src/cpp/dds/rpc/impl/RPCServer.ipp @@ -70,7 +70,7 @@ types::RpcRequestDataType RPCServer::get_request( if (reason == eprosima::utils::event::AwakeReason::disabled) { - logDebug(AMLIPCPP_DDS_RPCSERVER, "ModelManager Node " << this << " finished processing data."); + logDebug(AMLIPCPP_DDS_RPCSERVER, *this << " finished processing data."); // Break thread execution break; diff --git a/amlip_cpp/src/cpp/node/collaborative_learning/ModelManagerReceiverNode.cpp b/amlip_cpp/src/cpp/node/collaborative_learning/ModelManagerReceiverNode.cpp index 9bfeb79f..6f7b20f3 100644 --- a/amlip_cpp/src/cpp/node/collaborative_learning/ModelManagerReceiverNode.cpp +++ b/amlip_cpp/src/cpp/node/collaborative_learning/ModelManagerReceiverNode.cpp @@ -16,32 +16,35 @@ * @file ModelManagerReceiverNode.cpp */ -#include #include +#include +#include #include -#include -#include #include #include +#include +#include namespace eprosima { namespace amlip { namespace node { +const uint32_t ModelManagerReceiverNode::REPLY_TIMEOUT_ = 2500; + ModelManagerReceiverNode::ModelManagerReceiverNode( types::AmlipIdDataType id, - types::ModelDataType& data, + types::ModelRequestDataType& data, uint32_t domain_id) : ParentNode(id, types::NodeKind::model_receiver, types::StateKind::stopped, domain_id, dds::utils::ignore_locals_domain_participant_qos( id.name().c_str())) , statistics_reader_(participant_->create_reader( dds::utils::MODEL_STATISTICS_TOPIC_NAME, - default_statistics_datareader_qos())) + default_statistics_datareader_qos())) // TODO: parametrize constructor , model_receiver_( - participant_->create_rpc_client(dds::utils::MODEL_TOPIC_NAME)) + participant_->create_rpc_client(dds::utils::MODEL_TOPIC_NAME)) , running_(false) , data_(data) { @@ -50,7 +53,7 @@ ModelManagerReceiverNode::ModelManagerReceiverNode( ModelManagerReceiverNode::ModelManagerReceiverNode( types::AmlipIdDataType id, - types::ModelDataType& data) + types::ModelRequestDataType& data) : ModelManagerReceiverNode(id, data, dds::Participant::default_domain_id()) { // Do nothing @@ -58,7 +61,7 @@ ModelManagerReceiverNode::ModelManagerReceiverNode( ModelManagerReceiverNode::ModelManagerReceiverNode( const char* name, - types::ModelDataType& data, + types::ModelRequestDataType& data, uint32_t domain_id) : ModelManagerReceiverNode(types::AmlipIdDataType(name), data, domain_id) { @@ -67,7 +70,7 @@ ModelManagerReceiverNode::ModelManagerReceiverNode( ModelManagerReceiverNode::ModelManagerReceiverNode( const char* name, - types::ModelDataType& data) + types::ModelRequestDataType& data) : ModelManagerReceiverNode(name, data, dds::Participant::default_domain_id()) { // Do nothing @@ -125,50 +128,62 @@ void ModelManagerReceiverNode::process_routine_( { while (running_) { + + logDebug(AMLIPCPP_NODE_MODELMANAGERRECEIVER, "Waiting for statistics..."); + statistics_reader_->wait_data_available(); + + if (!running_) + { + break; + } + eprosima::amlip::types::ModelStatisticsDataType statistics; try { - logDebug(AMLIPCPP_NODE_MODELMANAGERRECEIVER, "Waiting for statistics..."); - statistics_reader_->wait_data_available(); - - if (!running_) - { - break; - } - // Read statistics logDebug(AMLIPCPP_NODE_MODELMANAGERRECEIVER, "Statistics received. Reading..."); statistics = statistics_reader_->read(); + } + catch (const eprosima::utils::InconsistencyException& e) + { + std::cerr << e.what() << std::endl; + continue; + } + logDebug(AMLIPCPP_NODE_MODELMANAGERRECEIVER, + "ModelManagerReceiver Node " << *this << " read statistics :" << statistics << "."); - logDebug(AMLIPCPP_NODE_MODELMANAGERRECEIVER, - "ModelManagerReceiver Node " << *this << " read statistics :" << statistics << "."); + if (listener->statistics_received(statistics)) + { + // Send request + types::TaskId task_id = model_receiver_->send_request(data_, statistics.server_id()); - if (listener->statistics_received(statistics)) + eprosima::amlip::types::ModelReplyDataType model; + try { - // Send request - types::TaskId task_id = model_receiver_->send_request(data_, statistics.server_id()); - // Wait reply - eprosima::amlip::types::ModelSolutionDataType model = model_receiver_->get_reply(task_id); + model = model_receiver_->get_reply(task_id, REPLY_TIMEOUT_); - if (!running_) - { - break; - } - // Call callback - listener->model_received(model); - logDebug(AMLIPCPP_NODE_MODELMANAGERRECEIVER, "ModelManagerReceiver Node has received a model update."); + } + catch (const eprosima::utils::TimeoutException& e) + { + std::cerr << e.what() << '\n'; + continue; + } + if (!running_) + { + break; } - } - catch (const std::exception& e) - { - std::cerr << e.what() << std::endl; + + // Call callback + listener->model_received(model); + logDebug(AMLIPCPP_NODE_MODELMANAGERRECEIVER, "ModelManagerReceiver Node has received a model update."); } } + logDebug(AMLIPCPP_NODE_MODELMANAGERRECEIVER, "Finishing ModelManagerReceiver routine."); } @@ -179,7 +194,8 @@ eprosima::fastdds::dds::DataReaderQos ModelManagerReceiverNode::default_statisti qos.durability().kind = eprosima::fastdds::dds::DurabilityQosPolicyKind::TRANSIENT_LOCAL_DURABILITY_QOS; qos.reliability().kind = eprosima::fastdds::dds::ReliabilityQosPolicyKind::RELIABLE_RELIABILITY_QOS; qos.history().kind = eprosima::fastdds::dds::HistoryQosPolicyKind::KEEP_LAST_HISTORY_QOS; - qos.history().depth = 1; + //! Allow to process several statistics + qos.history().depth = 10; return qos; } diff --git a/amlip_cpp/src/cpp/node/collaborative_learning/ModelManagerSenderNode.cpp b/amlip_cpp/src/cpp/node/collaborative_learning/ModelManagerSenderNode.cpp index e74a4945..440cc79b 100644 --- a/amlip_cpp/src/cpp/node/collaborative_learning/ModelManagerSenderNode.cpp +++ b/amlip_cpp/src/cpp/node/collaborative_learning/ModelManagerSenderNode.cpp @@ -16,17 +16,17 @@ * @file ModelManagerSenderNode.cpp */ -#include #include - -#include +#include #include +#include + #include -#include -#include -#include #include +#include +#include +#include namespace eprosima { namespace amlip { @@ -42,11 +42,10 @@ ModelManagerSenderNode::ModelManagerSenderNode( dds::utils::MODEL_STATISTICS_TOPIC_NAME, default_statistics_datawriter_qos())) , model_sender_( - participant_->create_rpc_server(dds::utils::MODEL_TOPIC_NAME)) + participant_->create_rpc_server(dds::utils::MODEL_TOPIC_NAME)) , running_(false) { - statistics_.server_id(participant_->id()); logDebug(AMLIPCPP_DDS_MODELMANAGERSENDER, "Created new ModelManager Node: " << *this << "."); } @@ -70,31 +69,43 @@ ModelManagerSenderNode::~ModelManagerSenderNode() logDebug(AMLIPCPP_DDS_MODELMANAGERSENDER, "ModelManagerSender Node Destroyed."); } -void ModelManagerSenderNode::update_statistics( +void ModelManagerSenderNode::publish_statistics( const std::string& name, void* data, - const uint32_t size) + const uint32_t size, + bool copy_data /* = true */) { - statistics_.name(name); - statistics_.data(data, size); + //! Statistical data from models. + types::ModelStatisticsDataType statistics(name, data, size, copy_data); + + statistics.server_id(participant_->id()); // Send statistics - statistics_writer_->publish(statistics_); + statistics_writer_->publish(statistics); } -void ModelManagerSenderNode::update_statistics( +void ModelManagerSenderNode::publish_statistics( const std::string& name, - const std::string& data) + const std::vector& data, + bool copy_data /* = true */) { - update_statistics( + publish_statistics( name, - utils::copy_to_void_ptr(utils::cast_to_void_ptr(data.c_str()), data.length()), - data.length()); + utils::cast_to_void_ptr(data.data()), + data.size(), + copy_data); } -types::ModelStatisticsDataType ModelManagerSenderNode::statistics() +void ModelManagerSenderNode::publish_statistics( + const std::string& name, + const std::string& data, + bool copy_data /* = true */) { - return statistics_; + publish_statistics( + name, + utils::cast_to_void_ptr(data.c_str()), + data.length(), + copy_data); } void ModelManagerSenderNode::start( @@ -136,7 +147,7 @@ void ModelManagerSenderNode::process_routine_( while (running_) { // Wait request - types::RpcRequestDataType request = + types::RpcRequestDataType request = model_sender_->get_request(); if (!running_) @@ -145,10 +156,10 @@ void ModelManagerSenderNode::process_routine_( } // Call callback - eprosima::amlip::types::ModelSolutionDataType solution = + eprosima::amlip::types::ModelReplyDataType solution = model_replier->fetch_model(request.data()); - types::RpcReplyDataType reply( + types::RpcReplyDataType reply( request.client_id(), request.task_id(), participant_->id(), diff --git a/amlip_cpp/src/cpp/types/model/ModelStatisticsDataType.cpp b/amlip_cpp/src/cpp/types/model/ModelStatisticsDataType.cpp index 02e05278..b54ba35f 100644 --- a/amlip_cpp/src/cpp/types/model/ModelStatisticsDataType.cpp +++ b/amlip_cpp/src/cpp/types/model/ModelStatisticsDataType.cpp @@ -32,9 +32,9 @@ using namespace eprosima::fastcdr::exception; #include #include -#include -#include #include +#include +#include #include @@ -47,22 +47,77 @@ const char* ModelStatisticsDataType::TYPE_NAME_ = "AMLIP-MODEL-STATISTICS"; ModelStatisticsDataType::ModelStatisticsDataType() : name_("ModelStatisticsDataTypeName") + , data_(nullptr) + , data_size_(0) , has_been_allocated_(false) { + // Do nothing } ModelStatisticsDataType::ModelStatisticsDataType( const char* name) : name_(name) + , data_(nullptr) + , data_size_(0) , has_been_allocated_(false) { + // Do nothing } ModelStatisticsDataType::ModelStatisticsDataType( const std::string& name) : name_(name) + , data_(nullptr) + , data_size_(0) , has_been_allocated_(false) { + // Do nothing +} + +ModelStatisticsDataType::ModelStatisticsDataType( + const std::string& name, + void* data, + const uint32_t size, + bool copy_data /* = true */) + : name_(name) + , data_size_(size) + , has_been_allocated_(copy_data) +{ + if (copy_data) + { + data_ = std::malloc(size * sizeof(uint8_t)); + std::memcpy(data_, data, size); + } + else + { + data_ = data; + } +} + +ModelStatisticsDataType::ModelStatisticsDataType( + const std::string& name, + const std::vector& bytes, + bool copy_data /* = true */) + : ModelStatisticsDataType( + name, + utils::cast_to_void_ptr(bytes.data()), + bytes.size(), + copy_data) +{ + // Do nothing +} + +ModelStatisticsDataType::ModelStatisticsDataType( + const std::string& name, + const std::string& bytes, + bool copy_data /* = true */) + : ModelStatisticsDataType( + name, + utils::cast_to_void_ptr(bytes.c_str()), + bytes.length(), + copy_data) +{ + // Do nothing } ModelStatisticsDataType::~ModelStatisticsDataType() @@ -226,29 +281,15 @@ void* ModelStatisticsDataType::data() const return data_; } -void ModelStatisticsDataType::data( - const std::vector& bytes) -{ - data_ = utils::copy_to_void_ptr(utils::cast_to_void_ptr(bytes.data()), bytes.size()); - data_size_ = bytes.size(); - has_been_allocated_ = true; -} - -void ModelStatisticsDataType::data( - const std::string& bytes) +std::string ModelStatisticsDataType::to_string() const noexcept { - data_ = utils::copy_to_void_ptr(utils::cast_to_void_ptr(bytes.c_str()), bytes.length()); - data_size_ = bytes.length(); - has_been_allocated_ = true; + return std::string(static_cast(data_), data_size_); } -void ModelStatisticsDataType::data( - void* data, - const uint32_t size) +std::vector ModelStatisticsDataType::to_vector() const noexcept { - data_ = data; - data_size_ = size; - has_been_allocated_ = true; + ByteType* buffer = static_cast(data_); + return std::vector(buffer, buffer + data_size_); } uint32_t ModelStatisticsDataType::data_size() const @@ -286,7 +327,7 @@ void ModelStatisticsDataType::deserialize( dcdr >> data_size_; // Store enough space to deserialize the data - data_ = malloc(data_size_ * sizeof(uint8_t)); + data_ = std::malloc(data_size_ * sizeof(uint8_t)); // Deserialize array dcdr.deserializeArray(static_cast(data_), data_size_); diff --git a/amlip_cpp/test/blackbox/communication/collaborative_learning/CMakeLists.txt b/amlip_cpp/test/blackbox/communication/collaborative_learning/CMakeLists.txt index 265bae32..789f16c7 100644 --- a/amlip_cpp/test/blackbox/communication/collaborative_learning/CMakeLists.txt +++ b/amlip_cpp/test/blackbox/communication/collaborative_learning/CMakeLists.txt @@ -12,9 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -##################################### +######################################## # NODE MODEL MANAGER TESTS -##################################### +######################################## set(TEST_NAME modelManagerTest) @@ -35,3 +35,27 @@ add_blackbox_executable( "${TEST_LIST}" "${TEST_NEEDED_SOURCES}" ) + +######################################## +# NODE MODEL MANAGER TIMEOUT REPLY TESTS +######################################## + +set(TEST_NAME modelManagerTimeoutReplyTest) + +set(TEST_SOURCES + modelManagerTimeoutReplyTest.cpp + ) + +set(TEST_LIST + ping_pong + ) + +set(TEST_NEEDED_SOURCES + ) + +add_blackbox_executable( + "${TEST_NAME}" + "${TEST_SOURCES}" + "${TEST_LIST}" + "${TEST_NEEDED_SOURCES}" + ) diff --git a/amlip_cpp/test/blackbox/communication/collaborative_learning/modelManagerTest.cpp b/amlip_cpp/test/blackbox/communication/collaborative_learning/modelManagerTest.cpp index 3e5980aa..d6e76a96 100644 --- a/amlip_cpp/test/blackbox/communication/collaborative_learning/modelManagerTest.cpp +++ b/amlip_cpp/test/blackbox/communication/collaborative_learning/modelManagerTest.cpp @@ -43,7 +43,7 @@ class TestModelListener : public eprosima::amlip::node::ModelListener } virtual bool model_received ( - const eprosima::amlip::types::ModelSolutionDataType model) override + const eprosima::amlip::types::ModelReplyDataType model) override { logUser(AMLIPCPP_MANUAL_TEST, "Model received: " << model << " ."); @@ -64,23 +64,23 @@ class TestModelReplier : public eprosima::amlip::node::ModelReplier // Do nothing } - virtual eprosima::amlip::types::ModelSolutionDataType fetch_model ( - const eprosima::amlip::types::ModelDataType data) override + virtual eprosima::amlip::types::ModelReplyDataType fetch_model ( + const eprosima::amlip::types::ModelRequestDataType data) override { logUser(AMLIPCPP_MANUAL_TEST, "Processing data: " << data << " . Processing data..."); - eprosima::amlip::types::ModelSolutionDataType solution; - if (data.data() == "MobileNet V1") + eprosima::amlip::types::ModelReplyDataType solution; + if (data.to_string() == "MobileNet V1") { - solution = eprosima::amlip::types::ModelSolutionDataType("MOBILENET V1"); + solution = eprosima::amlip::types::ModelReplyDataType("MOBILENET V1"); } - else if (data.data() == "MobileNet V2") + else if (data.to_string() == "MobileNet V2") { - solution = eprosima::amlip::types::ModelSolutionDataType("MOBILENET V2"); + solution = eprosima::amlip::types::ModelReplyDataType("MOBILENET V2"); } else { - solution = eprosima::amlip::types::ModelSolutionDataType("Do not have this model :,("); + solution = eprosima::amlip::types::ModelReplyDataType("Do not have this model :,("); } logUser(AMLIPCPP_MANUAL_TEST, "Processed model: " << solution << " . Returning model..."); @@ -107,20 +107,20 @@ TEST(modelManagerTest, ping_pong) // Managers always send same model in this test // Create ModelManagerReceiver Node - eprosima::amlip::types::AmlipIdDataType id_receiver({"ModelManagerReceiver"}, {66, 66, 66, 66}); + eprosima::amlip::types::AmlipIdDataType id_receiver("ModelManagerReceiver"); // NOTE: this data must be created before nodes or nodes must stop before this is destroyed - eprosima::amlip::types::ModelDataType data("MobileNet V1"); + eprosima::amlip::types::ModelRequestDataType data("MobileNet V1"); eprosima::amlip::node::ModelManagerReceiverNode model_receiver_node(id_receiver, data); logUser(AMLIPCPP_MANUAL_TEST, "Node created: " << model_receiver_node << ". Creating model..."); // Create ModelManagerSender Node - eprosima::amlip::types::AmlipIdDataType id_sender({"ModelManagerSender"}, {66, 66, 66, 66}); + eprosima::amlip::types::AmlipIdDataType id_sender("ModelManagerSender"); eprosima::amlip::node::ModelManagerSenderNode model_sender_node(id_sender); // Create statistics data std::string data_str = "hello world"; - model_sender_node.update_statistics("v0", data_str); + model_sender_node.publish_statistics("v0", data_str); // Create waiter std::shared_ptr waiter = diff --git a/amlip_cpp/test/blackbox/communication/collaborative_learning/modelManagerTimeoutReplyTest.cpp b/amlip_cpp/test/blackbox/communication/collaborative_learning/modelManagerTimeoutReplyTest.cpp new file mode 100644 index 00000000..354163f5 --- /dev/null +++ b/amlip_cpp/test/blackbox/communication/collaborative_learning/modelManagerTimeoutReplyTest.cpp @@ -0,0 +1,169 @@ +// Copyright 2023 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include + +#include +#include + +#include +#include +#include + + +namespace test { + +class TestModelListener : public eprosima::amlip::node::ModelListener +{ +public: + + TestModelListener( + const std::shared_ptr& waiter) + : waiter_(waiter) + { + } + + virtual bool statistics_received ( + const eprosima::amlip::types::ModelStatisticsDataType statistics) override + { + // Decide if we want the model based on the statistics received + return true; + } + + virtual bool model_received ( + const eprosima::amlip::types::ModelReplyDataType model) override + { + logUser(AMLIPCPP_MANUAL_TEST, "Model received: " << model << " ."); + + waiter_->open(); + + return true; + } + + std::shared_ptr waiter_; +}; + +class TestModelReplier : public eprosima::amlip::node::ModelReplier +{ +public: + + TestModelReplier() + { + // Do nothing + } + + virtual eprosima::amlip::types::ModelReplyDataType fetch_model ( + const eprosima::amlip::types::ModelRequestDataType data) override + { + logUser(AMLIPCPP_MANUAL_TEST, "Processing data: " << data << " . Processing data..."); + + eprosima::amlip::types::ModelReplyDataType solution("MOBILENET V1"); + + logUser(AMLIPCPP_MANUAL_TEST, "Processed model: " << solution << " . Returning model..."); + + return solution; + } + +}; + +} /* namespace test */ + +using namespace eprosima::amlip; + +/** + * Launch 1 ModelManagerReceiverNode and 2 ModelManagerSenderNode. + * + * The first Sender node publishes its statistics and then stops. + * Simulating when a Sender sends its statistics and the Receiver requests + * its model, but the Receiver has already terminated, so Receiver waits for + * REPLY_TIMEOUT_ ms before continuing to listen to other statistics. + * + * The second Sender publishes its statistics and responds to the + * request from the Receiver. + * + * This test assesses how the ModelManagerReceiverNodes handle scenarios + * where the ModelManagerSenderNodes terminate unexpectedly. + * + * Models will be mocked with strings. + */ +TEST(modelManagerTimeoutReplyTest, ping_pong) +{ + // Activate log + eprosima::utils::Log::SetVerbosity(eprosima::utils::Log::Kind::Info); + { + + // Managers always send same model in this test + + // Create ModelManagerReceiver Node + eprosima::amlip::types::AmlipIdDataType id_receiver("ModelManagerReceiver"); + // NOTE: this data must be created before nodes or nodes must stop before this is destroyed + eprosima::amlip::types::ModelRequestDataType data("MobileNet V1"); + eprosima::amlip::node::ModelManagerReceiverNode model_receiver_node(id_receiver, data); + + logUser(AMLIPCPP_MANUAL_TEST, "Node created: " << model_receiver_node << ". Creating model..."); + + // Create ModelManagerSender Nodes + eprosima::amlip::types::AmlipIdDataType id_sender_1("ModelManagerSender_1"); + eprosima::amlip::node::ModelManagerSenderNode model_sender_node_1(id_sender_1); + + eprosima::amlip::types::AmlipIdDataType id_sender_2("ModelManagerSender_2"); + eprosima::amlip::node::ModelManagerSenderNode model_sender_node_2(id_sender_2); + + // Create statistics data + std::string data_str_1 = "Hello world, I'm going to die."; + model_sender_node_1.publish_statistics("v0", data_str_1); + + // Create waiter_receiver + std::shared_ptr waiter_receiver = + std::make_shared(false, true); + + // Create listener + std::shared_ptr listener = + std::make_shared(waiter_receiver); + + std::shared_ptr replier = + std::make_shared(); + + // Statistics are sent due to transient local qos even if the node is stopped + // but, since the inner RPCReader is disabled, no reply is sent + model_sender_node_1.stop(); + + // Start nodes + model_receiver_node.start(listener); + + // Create statistics data + std::string data_str_2 = "Hello world, I'm working."; + model_sender_node_2.publish_statistics("v1", data_str_2); + + model_sender_node_2.start(replier); + + // Wait solution + waiter_receiver->wait(); + + // Stop nodes + model_receiver_node.stop(); + model_sender_node_2.stop(); + } + logUser(AMLIPCPP_MANUAL_TEST, "Finishing test..."); + +} + +int main( + int argc, + char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/amlip_cpp/test/manual/dds/rpcclient.cpp b/amlip_cpp/test/manual/dds/rpcclient.cpp index 503483c2..8fbb0c53 100644 --- a/amlip_cpp/test/manual/dds/rpcclient.cpp +++ b/amlip_cpp/test/manual/dds/rpcclient.cpp @@ -22,11 +22,11 @@ #include #include -#include -#include -#include +#include +#include #include +#include int main( int argc, diff --git a/amlip_cpp/test/manual/dds/rpcserver.cpp b/amlip_cpp/test/manual/dds/rpcserver.cpp index ff89cc99..ee910907 100644 --- a/amlip_cpp/test/manual/dds/rpcserver.cpp +++ b/amlip_cpp/test/manual/dds/rpcserver.cpp @@ -23,11 +23,11 @@ #include #include -#include -#include -#include +#include +#include #include +#include class CustomRequestReplier : public eprosima::amlip::dds::RequestReplier diff --git a/amlip_cpp/test/manual/node/model_manager_receiver.cpp b/amlip_cpp/test/manual/node/model_manager_receiver.cpp index 4133f39f..93080e76 100644 --- a/amlip_cpp/test/manual/node/model_manager_receiver.cpp +++ b/amlip_cpp/test/manual/node/model_manager_receiver.cpp @@ -22,8 +22,8 @@ #include #include -#include #include +#include class CustomModelListener : public eprosima::amlip::node::ModelListener @@ -44,7 +44,7 @@ class CustomModelListener : public eprosima::amlip::node::ModelListener } virtual bool model_received ( - const eprosima::amlip::types::ModelSolutionDataType model) override + const eprosima::amlip::types::ModelReplyDataType model) override { logUser(AMLIPCPP_MANUAL_TEST, "Model received: " << model << " ."); @@ -69,7 +69,7 @@ int main( { // Create ModelManagerReceiver Node eprosima::amlip::types::AmlipIdDataType id({"ModelManagerReceiver"}, {66, 66, 66, 66}); - eprosima::amlip::types::ModelDataType data("MobileNet V1"); + eprosima::amlip::types::ModelRequestDataType data("MobileNet V1"); eprosima::amlip::node::ModelManagerReceiverNode model_receiver_node(id, data); logUser(AMLIPCPP_MANUAL_TEST, "Node created: " << model_receiver_node << ". Creating model..."); diff --git a/amlip_cpp/test/manual/node/model_manager_sender.cpp b/amlip_cpp/test/manual/node/model_manager_sender.cpp index c1937f35..0f4af248 100644 --- a/amlip_cpp/test/manual/node/model_manager_sender.cpp +++ b/amlip_cpp/test/manual/node/model_manager_sender.cpp @@ -22,13 +22,12 @@ #include #include +#include #include -#include -#include +#include +#include #include -#include - class CustomModelReplier : public eprosima::amlip::node::ModelReplier { @@ -41,13 +40,13 @@ class CustomModelReplier : public eprosima::amlip::node::ModelReplier // Do nothing } - virtual eprosima::amlip::types::ModelSolutionDataType fetch_model ( - const eprosima::amlip::types::ModelDataType data) override + virtual eprosima::amlip::types::ModelReplyDataType fetch_model ( + const eprosima::amlip::types::ModelRequestDataType request) override { - logUser(AMLIPCPP_MANUAL_TEST, "Processing data: " << data << " . Processing data..."); + logUser(AMLIPCPP_MANUAL_TEST, "Processing request: " << request << " . Processing request..."); - // Create new solution from data here - eprosima::amlip::types::ModelSolutionDataType solution("MOBILENET V1"); + // Create new solution from request here + eprosima::amlip::types::ModelReplyDataType solution("MOBILENET V1"); logUser(AMLIPCPP_MANUAL_TEST, "Processed model: " << solution << " . Returning model..."); @@ -78,7 +77,7 @@ int main( // Create statistics data std::string data = "hello world"; - model_sender_node.update_statistics("v0", data); + model_sender_node.publish_statistics("v0", data, false); logUser(AMLIPCPP_MANUAL_TEST, "Node created: " << model_sender_node << ". Creating model..."); diff --git a/amlip_cpp/test/unittest/node/nodeCreationTest.cpp b/amlip_cpp/test/unittest/node/nodeCreationTest.cpp index a95763ee..f72885a6 100644 --- a/amlip_cpp/test/unittest/node/nodeCreationTest.cpp +++ b/amlip_cpp/test/unittest/node/nodeCreationTest.cpp @@ -177,7 +177,7 @@ TEST(NodeCreationTest, create_model_sender) */ TEST(NodeCreationTest, create_model_receiver) { - eprosima::amlip::types::ModelDataType data("MobileNet V1"); + eprosima::amlip::types::ModelRequestDataType data("MobileNet V1"); node::ModelManagerReceiverNode node("TestNode", data); diff --git a/amlip_demo_nodes/amlip_collaborative_learning_demo/amlip_collaborative_learning_demo/model_receiver_custom.py b/amlip_demo_nodes/amlip_collaborative_learning_demo/amlip_collaborative_learning_demo/model_receiver_custom.py index b17772a8..99067c3c 100644 --- a/amlip_demo_nodes/amlip_collaborative_learning_demo/amlip_collaborative_learning_demo/model_receiver_custom.py +++ b/amlip_demo_nodes/amlip_collaborative_learning_demo/amlip_collaborative_learning_demo/model_receiver_custom.py @@ -16,8 +16,8 @@ from amlip_py.node.ModelManagerReceiverNode import ModelManagerReceiverNode, ModelListener from amlip_py.types.AmlipIdDataType import AmlipIdDataType -from amlip_py.types.ModelDataType import ModelDataType -from amlip_py.types.ModelSolutionDataType import ModelSolutionDataType +from amlip_py.types.ModelReplyDataType import ModelReplyDataType +from amlip_py.types.ModelRequestDataType import ModelRequestDataType from amlip_py.types.ModelStatisticsDataType import ModelStatisticsDataType # Domain ID @@ -37,7 +37,7 @@ def statistics_received( def model_received( self, - model: ModelSolutionDataType) -> bool: + model: ModelReplyDataType) -> bool: print(f'Model reply received from server\n' f' solution: {model.to_string()}') @@ -51,7 +51,7 @@ def main(): """Execute main routine.""" # Create request - data = ModelDataType('MobileNet V1') + data = ModelRequestDataType('MobileNet V1') id = AmlipIdDataType('ModelManagerReceiver') id.set_id([15, 25, 35, 45]) diff --git a/amlip_demo_nodes/amlip_collaborative_learning_demo/amlip_collaborative_learning_demo/model_receiver_lambda.py b/amlip_demo_nodes/amlip_collaborative_learning_demo/amlip_collaborative_learning_demo/model_receiver_lambda.py index c0955c1a..9c6145a1 100644 --- a/amlip_demo_nodes/amlip_collaborative_learning_demo/amlip_collaborative_learning_demo/model_receiver_lambda.py +++ b/amlip_demo_nodes/amlip_collaborative_learning_demo/amlip_collaborative_learning_demo/model_receiver_lambda.py @@ -16,8 +16,8 @@ from amlip_py.node.ModelManagerReceiverNode import ModelManagerReceiverNode from amlip_py.types.AmlipIdDataType import AmlipIdDataType -from amlip_py.types.ModelDataType import ModelDataType -from amlip_py.types.ModelSolutionDataType import ModelSolutionDataType +from amlip_py.types.ModelReplyDataType import ModelReplyDataType +from amlip_py.types.ModelRequestDataType import ModelRequestDataType from amlip_py.types.ModelStatisticsDataType import ModelStatisticsDataType # Domain ID @@ -34,7 +34,7 @@ def statistics_received( def model_received( - model: ModelSolutionDataType) -> bool: + model: ModelReplyDataType) -> bool: print(f'Model reply received from server\n' f' solution: {model.to_string()}') @@ -48,7 +48,7 @@ def main(): """Execute main routine.""" # Create request - data = ModelDataType('MobileNet V1') + data = ModelRequestDataType('MobileNet V1') id = AmlipIdDataType('ModelManagerReceiver') id.set_id([15, 25, 35, 45]) diff --git a/amlip_demo_nodes/amlip_collaborative_learning_demo/amlip_collaborative_learning_demo/model_receiver_listener.py b/amlip_demo_nodes/amlip_collaborative_learning_demo/amlip_collaborative_learning_demo/model_receiver_listener.py index d1189745..300e3f08 100644 --- a/amlip_demo_nodes/amlip_collaborative_learning_demo/amlip_collaborative_learning_demo/model_receiver_listener.py +++ b/amlip_demo_nodes/amlip_collaborative_learning_demo/amlip_collaborative_learning_demo/model_receiver_listener.py @@ -16,8 +16,8 @@ from amlip_py.node.ModelManagerReceiverNode import ModelManagerReceiverNode, ModelListenerLambda from amlip_py.types.AmlipIdDataType import AmlipIdDataType -from amlip_py.types.ModelDataType import ModelDataType -from amlip_py.types.ModelSolutionDataType import ModelSolutionDataType +from amlip_py.types.ModelReplyDataType import ModelReplyDataType +from amlip_py.types.ModelRequestDataType import ModelRequestDataType from amlip_py.types.ModelStatisticsDataType import ModelStatisticsDataType # Domain ID @@ -34,7 +34,7 @@ def statistics_received( def model_received( - model: ModelSolutionDataType) -> bool: + model: ModelReplyDataType) -> bool: print(f'Model reply received from server\n' f' solution: {model.to_string()}') @@ -48,7 +48,7 @@ def main(): """Execute main routine.""" # Create request - data = ModelDataType('MobileNet V1') + data = ModelRequestDataType('MobileNet V1') id = AmlipIdDataType('ModelManagerReceiver') id.set_id([15, 25, 35, 45]) diff --git a/amlip_demo_nodes/amlip_collaborative_learning_demo/amlip_collaborative_learning_demo/model_sender_custom.py b/amlip_demo_nodes/amlip_collaborative_learning_demo/amlip_collaborative_learning_demo/model_sender_custom.py index c73ac158..04497682 100644 --- a/amlip_demo_nodes/amlip_collaborative_learning_demo/amlip_collaborative_learning_demo/model_sender_custom.py +++ b/amlip_demo_nodes/amlip_collaborative_learning_demo/amlip_collaborative_learning_demo/model_sender_custom.py @@ -16,8 +16,8 @@ from amlip_py.node.ModelManagerSenderNode import ModelManagerSenderNode, ModelReplier from amlip_py.types.AmlipIdDataType import AmlipIdDataType -from amlip_py.types.ModelDataType import ModelDataType -from amlip_py.types.ModelSolutionDataType import ModelSolutionDataType +from amlip_py.types.ModelReplyDataType import ModelReplyDataType +from amlip_py.types.ModelRequestDataType import ModelRequestDataType # Domain ID DOMAIN_ID = 166 @@ -30,17 +30,17 @@ class CustomModelReplier(ModelReplier): def fetch_model( self, - model: ModelDataType) -> ModelSolutionDataType: + request: ModelRequestDataType) -> ModelReplyDataType: - solution = ModelSolutionDataType(model.to_string().upper()) + reply = ModelReplyDataType(request.to_string().upper()) print(f'Model request received from client\n' - f' model: {model.to_string()}\n' - f' solution: {solution.to_string()}') + f' request: {request.to_string()}\n' + f' reply: {reply.to_string()}') waiter.open() - return solution + return reply def main(): @@ -58,7 +58,7 @@ def main(): print(f'Node created: {model_sender_node.get_id()}. ' 'Already processing models.') - model_sender_node.update_statistics( + model_sender_node.publish_statistics( 'ModelManagerSenderStatistics', 'hello world') diff --git a/amlip_demo_nodes/amlip_collaborative_learning_demo/amlip_collaborative_learning_demo/model_sender_lambda.py b/amlip_demo_nodes/amlip_collaborative_learning_demo/amlip_collaborative_learning_demo/model_sender_lambda.py index 2c14685c..92a7a68b 100644 --- a/amlip_demo_nodes/amlip_collaborative_learning_demo/amlip_collaborative_learning_demo/model_sender_lambda.py +++ b/amlip_demo_nodes/amlip_collaborative_learning_demo/amlip_collaborative_learning_demo/model_sender_lambda.py @@ -16,8 +16,8 @@ from amlip_py.node.ModelManagerSenderNode import ModelManagerSenderNode from amlip_py.types.AmlipIdDataType import AmlipIdDataType -from amlip_py.types.ModelDataType import ModelDataType -from amlip_py.types.ModelSolutionDataType import ModelSolutionDataType +from amlip_py.types.ModelReplyDataType import ModelReplyDataType +from amlip_py.types.ModelRequestDataType import ModelRequestDataType # Domain ID DOMAIN_ID = 166 @@ -27,17 +27,17 @@ def fetch_model( - model: ModelDataType) -> ModelSolutionDataType: + request: ModelRequestDataType) -> ModelReplyDataType: - solution = ModelSolutionDataType(model.to_string().upper()) + reply = ModelReplyDataType(request.to_string().upper()) print(f'Model request received from client\n' - f' model: {model.to_string()}\n' - f' solution: {solution.to_string()}') + f' request: {request.to_string()}\n' + f' reply: {reply.to_string()}') waiter.open() - return solution + return reply def main(): @@ -55,7 +55,7 @@ def main(): print(f'Node created: {model_sender_node.get_id()}. ' 'Already processing models.') - model_sender_node.update_statistics( + model_sender_node.publish_statistics( 'ModelManagerSenderStatistics', 'hello world') diff --git a/amlip_demo_nodes/amlip_collaborative_learning_demo/amlip_collaborative_learning_demo/model_sender_listener.py b/amlip_demo_nodes/amlip_collaborative_learning_demo/amlip_collaborative_learning_demo/model_sender_listener.py index 32dfe5a8..8885f182 100644 --- a/amlip_demo_nodes/amlip_collaborative_learning_demo/amlip_collaborative_learning_demo/model_sender_listener.py +++ b/amlip_demo_nodes/amlip_collaborative_learning_demo/amlip_collaborative_learning_demo/model_sender_listener.py @@ -16,8 +16,8 @@ from amlip_py.node.ModelManagerSenderNode import ModelManagerSenderNode, ModelReplierLambda from amlip_py.types.AmlipIdDataType import AmlipIdDataType -from amlip_py.types.ModelDataType import ModelDataType -from amlip_py.types.ModelSolutionDataType import ModelSolutionDataType +from amlip_py.types.ModelReplyDataType import ModelReplyDataType +from amlip_py.types.ModelRequestDataType import ModelRequestDataType # Domain ID DOMAIN_ID = 166 @@ -27,17 +27,17 @@ def fetch_model( - model: ModelDataType) -> ModelSolutionDataType: + request: ModelRequestDataType) -> ModelReplyDataType: - solution = ModelSolutionDataType(model.to_string().upper()) + reply = ModelReplyDataType(request.to_string().upper()) print(f'Model request received from client\n' - f' model: {model.to_string()}\n' - f' solution: {solution.to_string()}') + f' request: {request.to_string()}\n' + f' reply: {reply.to_string()}') waiter.open() - return solution + return reply def main(): @@ -55,7 +55,7 @@ def main(): print(f'Node created: {model_sender_node.get_id()}. ' 'Already processing models.') - model_sender_node.update_statistics( + model_sender_node.publish_statistics( 'ModelManagerSenderStatistics', 'hello world') diff --git a/amlip_docs/index.rst b/amlip_docs/index.rst index 29d51c24..e82f17c7 100644 --- a/amlip_docs/index.rst +++ b/amlip_docs/index.rst @@ -61,6 +61,7 @@ Scenarios Nodes + Tools .. _index_developer_manual: diff --git a/amlip_docs/rst/appendixes/glossary.rst b/amlip_docs/rst/appendixes/glossary.rst index 1df7d2ca..ff258d62 100644 --- a/amlip_docs/rst/appendixes/glossary.rst +++ b/amlip_docs/rst/appendixes/glossary.rst @@ -64,6 +64,9 @@ DDS Specification: ``_. More information in :ref:`User Manual section `. + Domain Id + Virtual partition for DDS networks. + Endpoint Individual Entity that can :term:`Subscribe` or :term:`Publish` in a specific :term:`Topic`. diff --git a/amlip_docs/rst/demo/collaborative_learning.rst b/amlip_docs/rst/demo/collaborative_learning.rst index 19cdae37..69cb8fee 100644 --- a/amlip_docs/rst/demo/collaborative_learning.rst +++ b/amlip_docs/rst/demo/collaborative_learning.rst @@ -86,7 +86,7 @@ Whenever it is ``False``, threads wait. :language: python :lines: 27 -The ``CustomModelListener`` class is responsible for listens to :ref:`user_manual_scenarios_collaborative_learning_statistics` and :ref:`user_manual_scenarios_collaborative_learning_solution` messages received from a :ref:`user_manual_nodes_model_sender`. +The ``CustomModelListener`` class is responsible for listens to :ref:`user_manual_scenarios_collaborative_learning_statistics` and :ref:`user_manual_scenarios_collaborative_learning_model_reply` messages received from a :ref:`user_manual_nodes_model_sender`. This class is supposed to be implemented by the user in order to process the messages received from other nodes in the network. .. literalinclude:: /../amlip_demo_nodes/amlip_collaborative_learning_demo/amlip_collaborative_learning_demo/model_receiver_custom.py @@ -101,7 +101,7 @@ We define the ``main`` function. We create an instance of ``ModelManagerReceiverNode``. The first thing the constructor gets is the id of the participant associated with the node. -Then the data which is a ``ModelDataType`` with the request message. +Then the data which is a ``ModelRequestDataType`` with the request message. And also we specified the domain equal to the ``DOMAIN_ID`` variable. .. literalinclude:: /../amlip_demo_nodes/amlip_collaborative_learning_demo/amlip_collaborative_learning_demo/model_receiver_custom.py @@ -158,7 +158,7 @@ Whenever it is ``False``, threads wait. :language: python :lines: 26 -The ``CustomModelReplier`` class is responsible for listens to :ref:`user_manual_scenarios_collaborative_learning_model` request messages received from a :ref:`user_manual_nodes_model_receiver`. +The ``CustomModelReplier`` class is responsible for listens to :ref:`user_manual_scenarios_collaborative_learning_model_request` request messages received from a :ref:`user_manual_nodes_model_receiver`. This class is supposed to be implemented by the user in order to process the messages. .. literalinclude:: /../amlip_demo_nodes/amlip_collaborative_learning_demo/amlip_collaborative_learning_demo/model_sender_custom.py @@ -179,7 +179,7 @@ And also we specified the domain equal to the ``DOMAIN_ID`` variable. :language: python :lines: 49-56 -Call the ``update_statistics()`` function, which fills the :ref:`user_manual_scenarios_collaborative_learning_statistics` and publishes it. +Call the ``publish_statistics()`` function, which fills a :ref:`user_manual_scenarios_collaborative_learning_statistics` and publishes it. .. literalinclude:: /../amlip_demo_nodes/amlip_collaborative_learning_demo/amlip_collaborative_learning_demo/model_sender_custom.py :language: python diff --git a/amlip_docs/rst/notes/notes.rst b/amlip_docs/rst/notes/notes.rst index 02ba8b71..36b08296 100644 --- a/amlip_docs/rst/notes/notes.rst +++ b/amlip_docs/rst/notes/notes.rst @@ -53,8 +53,8 @@ This release includes the following new **AML-IP Data Types**: * :ref:`Inference `: messages that represent a partial data-set. * :ref:`Inference Solution `: messages that represent the inference of a data-set. * :ref:`Model Statistics `: messages that represent statistical data from models. -* :ref:`Model `: messages that represent a problem model request. -* :ref:`Model Solution `: messages that represent a problem reply with the requested model. +* :ref:`Model `: messages that represent a problem model request. +* :ref:`Model Solution `: messages that represent a problem reply with the requested model. This release includes the following **Demos**: diff --git a/amlip_docs/rst/user_manual/nodes/model_manager_receiver.rst b/amlip_docs/rst/user_manual/nodes/model_manager_receiver.rst index f8915b1a..1f6b8cb6 100644 --- a/amlip_docs/rst/user_manual/nodes/model_manager_receiver.rst +++ b/amlip_docs/rst/user_manual/nodes/model_manager_receiver.rst @@ -8,7 +8,7 @@ Model Manager Receiver Node This kind of Node performs the active (client) action of :ref:`user_manual_scenarios_collaborative_learning`. This node receives statistics about models and sends a request if it is interested in a particular one. -Then, waits for the arrival of the requested model, serialized as :ref:`user_manual_scenarios_collaborative_learning_solution`. +Then, waits for the arrival of the requested model, serialized as :ref:`user_manual_scenarios_collaborative_learning_model_reply`. Example of Usage @@ -34,8 +34,8 @@ Steps #include #include - #include - #include + #include + #include #include #include @@ -60,7 +60,7 @@ Steps } virtual bool model_received ( - const eprosima::amlip::types::ModelSolutionDataType model) override + const eprosima::amlip::types::ModelReplyDataType model) override { std::cout << "Model received: " << model << " ." << std::endl; @@ -76,7 +76,7 @@ Steps eprosima::amlip::types::AmlipIdDataType id({"ModelManagerSender"}, {10, 20, 30, 40}); // Create the data - eprosima::amlip::types::ModelDataType data("MobileNet V1"); + eprosima::amlip::types::ModelRequestDataType data("MobileNet V1"); // Create ModelManagerReceiver Node eprosima::amlip::node::ModelManagerReceiverNode model_receiver_node(id, data); @@ -105,8 +105,8 @@ Steps from py_utils.wait.BooleanWaitHandler import BooleanWaitHandler from amlip_py.types.AmlipIdDataType import AmlipIdDataType - from amlip_py.types.ModelDataType import ModelDataType - from amlip_py.types.ModelSolutionDataType import ModelSolutionDataType + from amlip_py.types.ModelRequestDataType import ModelRequestDataType + from amlip_py.types.ModelReplyDataType import ModelReplyDataType from amlip_py.types.ModelStatisticsDataType import ModelStatisticsDataType from amlip_py.node.ModelManagerReceiverNode import ModelManagerReceiverNode, ModelListener @@ -121,7 +121,7 @@ Steps def model_received( self, - model: ModelSolutionDataType) -> bool: + model: ModelReplyDataType) -> bool: print(f'Model reply received from server\n' f' solution: {model.to_string()}') @@ -130,7 +130,7 @@ Steps return True # Create the data - data = ModelDataType('MobileNet V1') + data = ModelRequestDataType('MobileNet V1') # Create the Id of the node id = AmlipIdDataType('ModelManagerReceiver') diff --git a/amlip_docs/rst/user_manual/nodes/model_manager_sender.rst b/amlip_docs/rst/user_manual/nodes/model_manager_sender.rst index fbd7bf05..aea07e75 100644 --- a/amlip_docs/rst/user_manual/nodes/model_manager_sender.rst +++ b/amlip_docs/rst/user_manual/nodes/model_manager_sender.rst @@ -8,8 +8,8 @@ Model Manager Sender Node This kind of Node performs the passive (server) action of :ref:`user_manual_scenarios_collaborative_learning`. This node sends statistics about the models it manages. -Then, waits for a Model request serialized as :ref:`user_manual_scenarios_collaborative_learning_model`. -Once received, a user-implemented callback (`fetch_model`) is executed, whose output should be the requested model in the form of a :ref:`user_manual_scenarios_collaborative_learning_solution`. +Then, waits for a Model request serialized as :ref:`user_manual_scenarios_collaborative_learning_model_request`. +Once received, a user-implemented callback (`fetch_model`) is executed, whose output should be the requested model in the form of a :ref:`user_manual_scenarios_collaborative_learning_model_reply`. Example of Usage @@ -35,8 +35,8 @@ Steps #include #include - #include - #include + #include + #include #include #include @@ -53,13 +53,13 @@ Steps // Do nothing } - virtual eprosima::amlip::types::ModelSolutionDataType fetch_model ( - const eprosima::amlip::types::ModelDataType data) override + virtual eprosima::amlip::types::ModelReplyDataType fetch_model ( + const eprosima::amlip::types::ModelRequestDataType data) override { std::cout << "Processing data: " << data << " . Processing data..." << std::endl; // Create new solution from data here - eprosima::amlip::types::ModelSolutionDataType solution("MOBILENET V1"); + eprosima::amlip::types::ModelReplyDataType solution("MOBILENET V1"); std::cout << "Processed model: " << solution << " . Returning model..." << std::endl; @@ -79,7 +79,7 @@ Steps // Create statistics data std::string data = "hello world"; - model_sender_node.update_statistics("v0", data); + model_sender_node.publish_statistics("v0", data); // Create waiter std::shared_ptr waiter = @@ -105,8 +105,8 @@ Steps from py_utils.wait.BooleanWaitHandler import BooleanWaitHandler from amlip_py.types.AmlipIdDataType import AmlipIdDataType - from amlip_py.types.ModelDataType import ModelDataType - from amlip_py.types.ModelSolutionDataType import ModelSolutionDataType + from amlip_py.types.ModelRequestDataType import ModelRequestDataType + from amlip_py.types.ModelReplyDataType import ModelReplyDataType from amlip_py.types.ModelStatisticsDataType import ModelStatisticsDataType from amlip_py.node.ModelManagerSenderNode import ModelManagerSenderNode, ModelReplier @@ -116,8 +116,8 @@ Steps def fetch_model( self, - model: ModelDataType) -> ModelSolutionDataType: - solution = ModelSolutionDataType(model.to_string().upper()) + model: ModelRequestDataType) -> ModelReplyDataType: + solution = ModelReplyDataType(model.to_string().upper()) print(f'Model request received from client\n' f' model: {model.to_string()}\n' f' solution: {solution.to_string()}') @@ -135,7 +135,7 @@ Steps id=id, domain=100) - model_sender_node.update_statistics( + model_sender_node.publish_statistics( 'ModelManagerSenderStatistics', 'hello world') diff --git a/amlip_docs/rst/user_manual/scenarios/collaborative_learning.rst b/amlip_docs/rst/user_manual/scenarios/collaborative_learning.rst index 3fb74032..413bf5f9 100644 --- a/amlip_docs/rst/user_manual/scenarios/collaborative_learning.rst +++ b/amlip_docs/rst/user_manual/scenarios/collaborative_learning.rst @@ -11,19 +11,19 @@ This intends to lead towards a more complex and accurate model. It leverages the :ref:`protocols_dds_rpc` communication protocol/paradigm in order to exchange all required information (model requests/replies) in an efficient way. The Model Manager Sender Nodes publish :ref:`user_manual_scenarios_collaborative_learning_statistics` 's while the Model Manager Receiver Nodes listen to them. -When a :ref:`user_manual_nodes_model_receiver` is interested in a model based on its :ref:`user_manual_scenarios_collaborative_learning_statistics`, it sends a :ref:`user_manual_scenarios_collaborative_learning_model` request to the Model Manager Sender Node that sent the :ref:`user_manual_scenarios_collaborative_learning_statistics`. -The :ref:`user_manual_nodes_model_sender` will respond with a :ref:`user_manual_scenarios_collaborative_learning_solution`. +When a :ref:`user_manual_nodes_model_receiver` is interested in a model based on its :ref:`user_manual_scenarios_collaborative_learning_statistics`, it sends a :ref:`user_manual_scenarios_collaborative_learning_model_request` request to the Model Manager Sender Node that sent the :ref:`user_manual_scenarios_collaborative_learning_statistics`. +The :ref:`user_manual_nodes_model_sender` will respond with a :ref:`user_manual_scenarios_collaborative_learning_model_reply`. .. figure:: /rst/figures/collaborative_learning_scenario.png :align: center :width: 80% -.. _user_manual_scenarios_collaborative_learning_model: +.. _user_manual_scenarios_collaborative_learning_model_request: -Model Data Type -=============== +Model Request Data Type +======================= -The **Model** Data Type represents a problem request. +The **Model Request** Data Type represents a problem request. Internally, *requests* sent from a *Model Manager Receiver Node* to a *Model Manager Sender Node* are treated as byte arrays of arbitrary size. So far, the interaction with this class could be done from a :code:`void*`, a byte array or a string. @@ -32,12 +32,12 @@ So far, the interaction with this class could be done from a :code:`void*`, a by A more specific Data Type will be implemented in future releases for efficiency improvements. -.. _user_manual_scenarios_collaborative_learning_solution: +.. _user_manual_scenarios_collaborative_learning_model_reply: -Model Solution Data Type -======================== +Model Reply Data Type +===================== -The **Solution** Data Type represents a problem reply with the requested model. +The **Model Reply** Data Type represents a problem reply with the requested model. The *replies* sent from a *Model Manager Sender Node* to a *Model Manager Receiver Node* are treated as a bytes array of arbitrary size. So far, the interaction with this class could be done from a :code:`void*`, a byte array or a string. diff --git a/amlip_docs/rst/user_manual/tools/agent.rst b/amlip_docs/rst/user_manual/tools/agent.rst new file mode 100644 index 00000000..44c7dabe --- /dev/null +++ b/amlip_docs/rst/user_manual/tools/agent.rst @@ -0,0 +1,189 @@ +.. include:: ../../exports/alias.include + +.. _user_manual_tools_agent: + +########## +Agent Tool +########## + +This tool launches an :ref:`user_manual_nodes_agent`, which is the node in charge of communicating a local node or AML-IP cluster with the rest of the network in :term:`WAN`\s. +It centralizes the :term:`WAN` discovery and communication, i.e. it is the bridge for all the nodes in their :term:`LAN`\s with the rest of the AML-IP components. + +Building the tool +================= + +If the tool package is not compiled, please refer to :ref:`developer_manual_installation_sources_linux_colcon` or run the command below. + +.. code-block:: bash + + colcon build --packages-up-to amlip_agent + +Once AML-IP packages are installed and built, source the workspace using the following command. + +.. code-block:: bash + + source install/setup.bash + +Application Arguments +===================== + +The Agent Tool supports several input arguments: + +.. list-table:: + :header-rows: 1 + + * - Command + - Option + - Long option + - Value + - Default Value + + * - :ref:`Help ` + - ``-h`` + - ``--help`` + - + - + + * - Entity + - ``-e`` + - ``--entity`` + - Agent Entity type. + - ``client`` + + * - Name + - ``-n`` + - ``--name`` + - Readable File Path + - ``amlip_agent`` + + * - DDS Domain + - ``-d`` + - ``--domain`` + - Configures the :term:`Domain Id`. + - ``0`` + + * - Connection Address + - ``-c`` + - ``--connection-address`` + - Address to connect. + - ``127.0.0.1`` + + * - Connection Port + - ``-p`` + - ``--connection-port`` + - Address connection port. + - ``12121`` + + * - Listening Address + - ``-l`` + - ``--listening-address`` + - Address where listen. + - ``127.0.0.1`` + + * - Listening Port + - ``-q`` + - ``--listening-port`` + - Address listening port. + - ``12121`` + + * - Transport + - ``-t`` + - ``--transport`` + - Use only TCPv4 or UDPv4 transport. + - ``TCPv4`` + +.. _user_manual_tool_agent_help_argument: + +Help Argument +------------- + +It shows the usage information of the tool. + +.. code-block:: console + + Usage: ./agent tool + + General options: + -h, --help + Produce help message. + -e, --entity + Agent Entity type (Default: client). Allowed options: + + • client -> Run an Agent Client Node. + + • server -> Run an Agent Server Node. + + • repeater -> Run an Agent Repeater Node. + + Client options: + -n, --name + Name (Default: amlip_agent). + -d, --domain + DDS domain ID (Default: 0). + -c, --connection-address
+ Address to connect (Default: 127.0.0.1). + -p, --connection-port + Address connection port (Default: 12121). + -t, --transport + Use only TCPv4 or UDPv4 transport. (Default: TCPv4). + + Server options: + -n, --name + Name (Default: agent_tool). + -d, --domain + DDS domain ID (Default: 0). + -l, --listening-address
+ Address where listen (Default: 127.0.0.1). + -q, --listening-port + Address listening port (Default: 12121). + -t, --transport + Use only TCPv4 or UDPv4 transport. (Default: TCPv4). + + Repeater options: + -n, --name + Name (Default: agent_tool). + -d, --domain + DDS domain ID (Default: 0). + -c, --connection-address
+ Address to connect (Default: 127.0.0.1). + -l, --listening-address
+ Address where listen (Default: 127.0.0.1). + -p, --connection-port + Address connection port (Default: 12121). + -q, --listening-port + Address listening port (Default: 12121). + -t, --transport + Use only TCPv4 or UDPv4 transport. (Default: TCPv4). + + +Run tool +======== + +Source the following file to setup the AML-IP environment: + +.. code-block:: bash + + source /install/setup.bash + +Launching an :ref:`Agent Client Node ` instance is as easy as executing the following command: + +.. code-block:: bash + + amlip_agent -e client -c 87.111.115.111 -p 18000 -t tcp + +To launch an :ref:`Agent Server Node `, execute: + +.. code-block:: bash + + amlip_agent -e server -l 87.111.115.111 -q 18000 -t tcp + +To launch an :ref:`Agent Repeater Node `, execute: + +.. code-block:: bash + + amlip_agent -e repeater -l 87.111.115.111 -q 18000 -t tcp + +Close tool +========== + +In order to stop the *Agent* tool, press ``Ctrl + C`` in the terminal where the process is running. diff --git a/amlip_docs/rst/user_manual/tools/tools.rst b/amlip_docs/rst/user_manual/tools/tools.rst new file mode 100644 index 00000000..b5417907 --- /dev/null +++ b/amlip_docs/rst/user_manual/tools/tools.rst @@ -0,0 +1,12 @@ +.. include:: ../../exports/alias.include + +.. _user_manual_tools: + +############ +AML-IP Tools +############ + +.. toctree:: + :maxdepth: 1 + + agent diff --git a/amlip_py/amlip_py/node/ModelManagerReceiverNode.py b/amlip_py/amlip_py/node/ModelManagerReceiverNode.py index 42b530cd..17960f2b 100644 --- a/amlip_py/amlip_py/node/ModelManagerReceiverNode.py +++ b/amlip_py/amlip_py/node/ModelManagerReceiverNode.py @@ -15,8 +15,8 @@ from amlip_py.types.AmlipIdDataType import AmlipIdDataType -from amlip_py.types.ModelDataType import ModelDataType -from amlip_py.types.ModelSolutionDataType import ModelSolutionDataType +from amlip_py.types.ModelReplyDataType import ModelReplyDataType +from amlip_py.types.ModelRequestDataType import ModelRequestDataType from amlip_py.types.ModelStatisticsDataType import ModelStatisticsDataType from amlip_swig import ModelManagerReceiverNode as cpp_ModelManagerReceiverNode @@ -30,7 +30,7 @@ class ModelListener(cpp_ModelListener): This object must be called by the ModelManagerReceiverNode to execute the statistics_received method with each ModelStatisticsDataType that is received from node and must return true or false. Must also execute the - model_received method on each ModelSolutionDataType that is received from node. + model_received method on each ModelReplyDataType that is received from node. """ def statistics_received( @@ -47,7 +47,7 @@ def statistics_received( def model_received( self, - model: ModelSolutionDataType) -> bool: + model: ModelReplyDataType) -> bool: """ Raise exception. @@ -82,7 +82,7 @@ def statistics_received( def model_received( self, - model: ModelSolutionDataType) -> bool: + model: ModelReplyDataType) -> bool: """Call internal lambda.""" return self.callback_model_(model) @@ -95,7 +95,7 @@ class ModelManagerReceiverNode(cpp_ModelManagerReceiverNode): def __init__( self, id: AmlipIdDataType | str, - data: ModelDataType, + data: ModelRequestDataType, domain: int = None): """ @@ -103,7 +103,7 @@ def __init__( Parameters ---------- id : AmlipIdDataType | str - data: ModelDataType + data: ModelRequestDataType domain : int """ diff --git a/amlip_py/amlip_py/node/ModelManagerSenderNode.py b/amlip_py/amlip_py/node/ModelManagerSenderNode.py index 977e180b..6125169f 100644 --- a/amlip_py/amlip_py/node/ModelManagerSenderNode.py +++ b/amlip_py/amlip_py/node/ModelManagerSenderNode.py @@ -15,8 +15,8 @@ from amlip_py.types.AmlipIdDataType import AmlipIdDataType -from amlip_py.types.ModelDataType import ModelDataType -from amlip_py.types.ModelSolutionDataType import ModelSolutionDataType +from amlip_py.types.ModelReplyDataType import ModelReplyDataType +from amlip_py.types.ModelRequestDataType import ModelRequestDataType from amlip_swig import ModelManagerSenderNode as cpp_ModelManagerSenderNode from amlip_swig import ModelReplier as cpp_ModelReplier @@ -27,13 +27,13 @@ class ModelReplier(cpp_ModelReplier): Model Replier class. This object must be called by the ModelManagerSenderNode to execute - the fetch_model method with each ModelDataType request that is received - from node and must return the ModelSolutionDataType reply. + the fetch_model method with each ModelRequestDataType request that is received + from node and must return the ModelReplyDataType reply. """ def fetch_model( self, - model: ModelDataType) -> ModelSolutionDataType: + model: ModelRequestDataType) -> ModelReplyDataType: """ Raise exception. @@ -48,7 +48,7 @@ class ModelReplierLambda(cpp_ModelReplier): Custom ModelReplier supporting to create it with a lambda function. This object is created with a lambda function that is stored inside and used for every - ModelDataType message received. + ModelRequestDataType message received. """ def __init__( @@ -60,7 +60,7 @@ def __init__( def fetch_model( self, - model: ModelDataType) -> ModelSolutionDataType: + model: ModelRequestDataType) -> ModelReplyDataType: """Call internal lambda.""" return self.callback_(model) @@ -89,12 +89,12 @@ def __init__( else: super().__init__(id, domain) - def update_statistics( + def publish_statistics( self, - name: str, - data: str) -> None: + name: str | bytes, + data: str | bytes) -> None: - cpp_ModelManagerSenderNode.update_statistics(self, name, data) + cpp_ModelManagerSenderNode.publish_statistics(self, name, data) def start( self, diff --git a/amlip_py/amlip_py/types/ModelSolutionDataType.py b/amlip_py/amlip_py/types/ModelReplyDataType.py similarity index 84% rename from amlip_py/amlip_py/types/ModelSolutionDataType.py rename to amlip_py/amlip_py/types/ModelReplyDataType.py index fb28061f..0e7b4ab6 100644 --- a/amlip_py/amlip_py/types/ModelSolutionDataType.py +++ b/amlip_py/amlip_py/types/ModelReplyDataType.py @@ -14,10 +14,10 @@ """AML-IP Model Solution data type API specification.""" -from amlip_swig import ModelSolutionDataType as cpp_ModelSolutionDataType +from amlip_swig import ModelReplyDataType as cpp_ModelReplyDataType -class ModelSolutionDataType(cpp_ModelSolutionDataType): +class ModelReplyDataType(cpp_ModelReplyDataType): """ Object that represents a Model (reply) sent from a ModelManagerSender Node to a ModelManagerReceiver one. @@ -41,9 +41,9 @@ def __init__( def __str__( self) -> str: """Serialize into a string.""" - return cpp_ModelSolutionDataType.to_string(self) + return cpp_ModelReplyDataType.to_string(self) def to_string( self) -> str: """Serialize into a string.""" - return cpp_ModelSolutionDataType.to_string(self) + return cpp_ModelReplyDataType.to_string(self) diff --git a/amlip_py/amlip_py/types/ModelDataType.py b/amlip_py/amlip_py/types/ModelRequestDataType.py similarity index 84% rename from amlip_py/amlip_py/types/ModelDataType.py rename to amlip_py/amlip_py/types/ModelRequestDataType.py index e6fa3dd1..69e05bb2 100644 --- a/amlip_py/amlip_py/types/ModelDataType.py +++ b/amlip_py/amlip_py/types/ModelRequestDataType.py @@ -14,10 +14,10 @@ """AML-IP Model data type API specification.""" -from amlip_swig import ModelDataType as cpp_ModelDataType +from amlip_swig import ModelRequestDataType as cpp_ModelRequestDataType -class ModelDataType(cpp_ModelDataType): +class ModelRequestDataType(cpp_ModelRequestDataType): """ Object that represents a Model (request) sent from a ModelManagerReceiver Node to a ModelManagerSender one. @@ -41,9 +41,9 @@ def __init__( def __str__( self) -> str: """Serialize into a string.""" - return cpp_ModelDataType.to_string(self) + return cpp_ModelRequestDataType.to_string(self) def to_string( self) -> str: """Serialize into a string.""" - return cpp_ModelDataType.to_string(self) + return cpp_ModelRequestDataType.to_string(self) diff --git a/amlip_py/amlip_py/types/ModelStatisticsDataType.py b/amlip_py/amlip_py/types/ModelStatisticsDataType.py index b6e6089c..822703df 100644 --- a/amlip_py/amlip_py/types/ModelStatisticsDataType.py +++ b/amlip_py/amlip_py/types/ModelStatisticsDataType.py @@ -14,9 +14,10 @@ """AML-IP Model Statistics data type API specification.""" -from amlip_swig import ModelStatisticsDataType as cpp_ModelStatisticsDataType from amlip_py.types.AmlipIdDataType import AmlipIdDataType +from amlip_swig import ModelStatisticsDataType as cpp_ModelStatisticsDataType + class ModelStatisticsDataType(cpp_ModelStatisticsDataType): """ @@ -26,7 +27,9 @@ class ModelStatisticsDataType(cpp_ModelStatisticsDataType): def __init__( self, - message: (str | bytes) = None): + message: (str | bytes) = None, + data: (str | bytes) = None, + size: int = None): """ Construct a new Model Statistics with statistics. Parameters @@ -34,7 +37,11 @@ def __init__( message: str or bytes Statistics to send to ModelManagerReceiver Node. """ - if (message): + if size: + super().__init__(message, data, size) + elif data: + super().__init__(message, data) + elif message: super().__init__(message) else: super().__init__() @@ -51,6 +58,12 @@ def get_data(self): """Get data referenced to this Id.""" return cpp_ModelStatisticsDataType.data(self) - def set_data(self, data): - """Set data referenced to this Id.""" - cpp_ModelStatisticsDataType.data(self, data) + def to_string( + self) -> str: + """Serialize Inference into a string.""" + return cpp_ModelStatisticsDataType.to_string(self) + + def to_vector( + self) -> bytes: + """Serialize Inference into bytes.""" + return cpp_ModelStatisticsDataType.to_vector(self) diff --git a/amlip_py/test/amlip_py/import/test_import_type.py b/amlip_py/test/amlip_py/import/test_import_type.py index 60b17007..e7036674 100644 --- a/amlip_py/test/amlip_py/import/test_import_type.py +++ b/amlip_py/test/amlip_py/import/test_import_type.py @@ -18,8 +18,8 @@ import amlip_py.types.JobSolutionDataType import amlip_py.types.StatusDataType import amlip_py.types.TaskId -import amlip_py.types.ModelDataType -import amlip_py.types.ModelSolutionDataType +import amlip_py.types.ModelRequestDataType +import amlip_py.types.ModelReplyDataType import amlip_py.types.ModelStatisticsDataType @@ -49,13 +49,13 @@ def test_task(): def test_model(): - """Test creation of ModelDataType.""" - _ = amlip_py.types.ModelDataType.ModelDataType() + """Test creation of ModelRequestDataType.""" + _ = amlip_py.types.ModelRequestDataType.ModelRequestDataType() def test_model_solution(): - """Test creation of ModelSolutionDataType.""" - _ = amlip_py.types.ModelSolutionDataType.ModelSolutionDataType() + """Test creation of ModelReplyDataType.""" + _ = amlip_py.types.ModelReplyDataType.ModelReplyDataType() def test_model_statistics(): diff --git a/amlip_py/test/amlip_py/node/blackbox/test_modelReceiverSenderNodeTest.py b/amlip_py/test/amlip_py/node/blackbox/test_modelReceiverSenderNodeTest.py index 104e76dc..7ad47bf7 100644 --- a/amlip_py/test/amlip_py/node/blackbox/test_modelReceiverSenderNodeTest.py +++ b/amlip_py/test/amlip_py/node/blackbox/test_modelReceiverSenderNodeTest.py @@ -14,11 +14,11 @@ from py_utils.wait.BooleanWaitHandler import BooleanWaitHandler -from amlip_py.node.ModelManagerSenderNode import ModelManagerSenderNode, ModelReplier from amlip_py.node.ModelManagerReceiverNode import ModelManagerReceiverNode, ModelListener +from amlip_py.node.ModelManagerSenderNode import ModelManagerSenderNode, ModelReplier from amlip_py.types.AmlipIdDataType import AmlipIdDataType -from amlip_py.types.ModelDataType import ModelDataType -from amlip_py.types.ModelSolutionDataType import ModelSolutionDataType +from amlip_py.types.ModelReplyDataType import ModelReplyDataType +from amlip_py.types.ModelRequestDataType import ModelRequestDataType from amlip_py.types.ModelStatisticsDataType import ModelStatisticsDataType # Domain ID @@ -32,9 +32,9 @@ class CustomModelReplier(ModelReplier): def fetch_model( self, - model: ModelDataType) -> ModelSolutionDataType: + model: ModelRequestDataType) -> ModelReplyDataType: - solution = ModelSolutionDataType(model.to_string().upper()) + solution = ModelReplyDataType(model.to_string().upper()) print(f'Model request received from client\n' f' model: {model.to_string()}\n' @@ -53,7 +53,7 @@ def statistics_received( def model_received( self, - model: ModelSolutionDataType) -> bool: + model: ModelReplyDataType) -> bool: print(f'Model reply received from server\n' f' solution: {model.to_string()}') @@ -67,7 +67,7 @@ def main(): """Execute main routine.""" # Create request - data = ModelDataType('MobileNet V1') + data = ModelRequestDataType('MobileNet V1') id_receiver = AmlipIdDataType('ModelManagerReceiver') id_receiver.set_id([66, 66, 66, 66]) @@ -93,7 +93,7 @@ def main(): print(f'Node created: {model_sender_node.get_id()}. ' 'Already processing models.') - model_sender_node.update_statistics( + model_sender_node.publish_statistics( 'ModelManagerSenderStatistics', 'hello world') diff --git a/amlip_py/test/manual/model_receiver_str_custom.py b/amlip_py/test/manual/model_receiver_str_custom.py index becfb640..158aa630 100644 --- a/amlip_py/test/manual/model_receiver_str_custom.py +++ b/amlip_py/test/manual/model_receiver_str_custom.py @@ -12,12 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. +import pickle as pkl + from py_utils.wait.BooleanWaitHandler import BooleanWaitHandler from amlip_py.node.ModelManagerReceiverNode import ModelManagerReceiverNode, ModelListener from amlip_py.types.AmlipIdDataType import AmlipIdDataType -from amlip_py.types.ModelDataType import ModelDataType -from amlip_py.types.ModelSolutionDataType import ModelSolutionDataType +from amlip_py.types.ModelReplyDataType import ModelReplyDataType +from amlip_py.types.ModelRequestDataType import ModelRequestDataType from amlip_py.types.ModelStatisticsDataType import ModelStatisticsDataType # Domain ID @@ -32,13 +34,27 @@ class CustomModelListener(ModelListener): def statistics_received( self, statistics: ModelStatisticsDataType) -> bool: - return True + + data = pkl.loads(bytes(statistics.to_vector())) + + print('\n\nStatistics received: \n') + print(data) + print('\n') + + if (float(data['size']) < 100): + print('Publish request.\n') + + return True + + return False def model_received( self, - model: ModelSolutionDataType) -> bool: - print(f'Model reply received from server\n' - f' solution: {model.to_string()}') + model: ModelReplyDataType) -> bool: + + print('\nReply received:\n') + print(model.to_string()) + print('\n') waiter.open() @@ -49,7 +65,7 @@ def main(): """Execute main routine.""" # Create request - data = ModelDataType('MobileNet V1') + data = ModelRequestDataType('MobileNet V1') id = AmlipIdDataType('ModelManagerReceiver') id.set_id([66, 66, 66, 66]) diff --git a/amlip_py/test/manual/model_receiver_str_lambda.py b/amlip_py/test/manual/model_receiver_str_lambda.py index 1ec86b9f..565bec1c 100644 --- a/amlip_py/test/manual/model_receiver_str_lambda.py +++ b/amlip_py/test/manual/model_receiver_str_lambda.py @@ -12,12 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. +import pickle as pkl + from py_utils.wait.BooleanWaitHandler import BooleanWaitHandler from amlip_py.node.ModelManagerReceiverNode import ModelManagerReceiverNode from amlip_py.types.AmlipIdDataType import AmlipIdDataType -from amlip_py.types.ModelDataType import ModelDataType -from amlip_py.types.ModelSolutionDataType import ModelSolutionDataType +from amlip_py.types.ModelReplyDataType import ModelReplyDataType +from amlip_py.types.ModelRequestDataType import ModelRequestDataType from amlip_py.types.ModelStatisticsDataType import ModelStatisticsDataType # Domain ID @@ -29,13 +31,27 @@ def statistics_received( statistics: ModelStatisticsDataType) -> bool: - return True + + data = pkl.loads(bytes(statistics.to_vector())) + + print('\n\nStatistics received: \n') + print(data) + print('\n') + + if (float(data['size']) < 100): + print('Publish request.\n') + + return True + + return False def model_received( - model: ModelSolutionDataType) -> bool: - print(f'Model reply received from server\n' - f' solution: {model.to_string()}') + model: ModelReplyDataType) -> bool: + + print('\nReply received:\n') + print(model.to_string()) + print('\n') waiter.open() @@ -46,7 +62,7 @@ def main(): """Execute main routine.""" # Create request - data = ModelDataType('MobileNet V1') + data = ModelRequestDataType('MobileNet V1') id = AmlipIdDataType('ModelManagerReceiver') id.set_id([66, 66, 66, 66]) diff --git a/amlip_py/test/manual/model_receiver_str_listener.py b/amlip_py/test/manual/model_receiver_str_listener.py index b635abc3..84eaef61 100644 --- a/amlip_py/test/manual/model_receiver_str_listener.py +++ b/amlip_py/test/manual/model_receiver_str_listener.py @@ -12,12 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. +import pickle as pkl + from py_utils.wait.BooleanWaitHandler import BooleanWaitHandler from amlip_py.node.ModelManagerReceiverNode import ModelManagerReceiverNode, ModelListenerLambda from amlip_py.types.AmlipIdDataType import AmlipIdDataType -from amlip_py.types.ModelDataType import ModelDataType -from amlip_py.types.ModelSolutionDataType import ModelSolutionDataType +from amlip_py.types.ModelReplyDataType import ModelReplyDataType +from amlip_py.types.ModelRequestDataType import ModelRequestDataType from amlip_py.types.ModelStatisticsDataType import ModelStatisticsDataType # Domain ID @@ -29,13 +31,27 @@ def statistics_received( statistics: ModelStatisticsDataType) -> bool: - return True + + data = pkl.loads(bytes(statistics.to_vector())) + + print('\n\nStatistics received: \n') + print(data) + print('\n') + + if (float(data['size']) < 100): + print('Publish request.\n') + + return True + + return False def model_received( - model: ModelSolutionDataType) -> bool: - print(f'Model reply received from server\n' - f' solution: {model.to_string()}') + model: ModelReplyDataType) -> bool: + + print('\nReply received:\n') + print(model.to_string()) + print('\n') waiter.open() @@ -46,7 +62,7 @@ def main(): """Execute main routine.""" # Create request - data = ModelDataType('MobileNet V1') + data = ModelRequestDataType('MobileNet V1') id = AmlipIdDataType('ModelManagerReceiver') id.set_id([66, 66, 66, 66]) diff --git a/amlip_py/test/manual/model_sender_str_custom.py b/amlip_py/test/manual/model_sender_str_custom.py index 0526e379..9dda02b6 100644 --- a/amlip_py/test/manual/model_sender_str_custom.py +++ b/amlip_py/test/manual/model_sender_str_custom.py @@ -12,12 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. +import pickle as pkl + from py_utils.wait.BooleanWaitHandler import BooleanWaitHandler from amlip_py.node.ModelManagerSenderNode import ModelManagerSenderNode, ModelReplier from amlip_py.types.AmlipIdDataType import AmlipIdDataType -from amlip_py.types.ModelDataType import ModelDataType -from amlip_py.types.ModelSolutionDataType import ModelSolutionDataType +from amlip_py.types.ModelReplyDataType import ModelReplyDataType +from amlip_py.types.ModelRequestDataType import ModelRequestDataType # Domain ID DOMAIN_ID = 166 @@ -30,15 +32,21 @@ class CustomModelReplier(ModelReplier): def fetch_model( self, - model: ModelDataType) -> ModelSolutionDataType: - solution = ModelSolutionDataType(model.to_string().upper()) - print(f'Model request received from client\n' - f' model: {model.to_string()}\n' - f' solution: {solution.to_string()}') + request: ModelRequestDataType) -> ModelReplyDataType: + + print('Request received:\n') + print(request.to_string()) + print('\n') + + reply = ModelReplyDataType(request.to_string().upper()) waiter.open() - return solution + print('Publish reply:\n') + print(request.to_string().upper()) + print('\n') + + return reply def main(): @@ -56,9 +64,20 @@ def main(): print(f'Node created: {model_sender_node.get_id()}. ' 'Already processing models.') - model_sender_node.update_statistics( + data = { + 'name': 'hello world', + 'size': 56 + } + + statistics_dump = pkl.dumps(data) + + print('\n\nPublish statistics: \n') + print(data) + print('\n') + + model_sender_node.publish_statistics( 'ModelManagerSenderStatistics', - 'hello world') + statistics_dump) model_sender_node.start( listener=CustomModelReplier()) diff --git a/amlip_py/test/manual/model_sender_str_lambda.py b/amlip_py/test/manual/model_sender_str_lambda.py index abb53ef1..505bdbb2 100644 --- a/amlip_py/test/manual/model_sender_str_lambda.py +++ b/amlip_py/test/manual/model_sender_str_lambda.py @@ -12,12 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. +import pickle as pkl + from py_utils.wait.BooleanWaitHandler import BooleanWaitHandler from amlip_py.node.ModelManagerSenderNode import ModelManagerSenderNode from amlip_py.types.AmlipIdDataType import AmlipIdDataType -from amlip_py.types.ModelDataType import ModelDataType -from amlip_py.types.ModelSolutionDataType import ModelSolutionDataType +from amlip_py.types.ModelReplyDataType import ModelReplyDataType +from amlip_py.types.ModelRequestDataType import ModelRequestDataType # Domain ID DOMAIN_ID = 166 @@ -27,15 +29,21 @@ def fetch_model( - model: ModelDataType) -> ModelSolutionDataType: - solution = ModelSolutionDataType(model.to_string().upper()) - print(f'Model request received from client\n' - f' model: {model.to_string()}\n' - f' solution: {solution.to_string()}') + request: ModelRequestDataType) -> ModelReplyDataType: + + print('Request received:\n') + print(request.to_string()) + print('\n') + + reply = ModelReplyDataType(request.to_string().upper()) waiter.open() - return solution + print('Publish reply:\n') + print(request.to_string().upper()) + print('\n') + + return reply def main(): @@ -53,9 +61,20 @@ def main(): print(f'Node created: {model_sender_node.get_id()}. ' 'Already processing models.') - model_sender_node.update_statistics( + data = { + 'name': 'hello world', + 'size': 56 + } + + statistics_dump = pkl.dumps(data) + + print('\n\nPublish statistics: \n') + print(data) + print('\n') + + model_sender_node.publish_statistics( 'ModelManagerSenderStatistics', - 'hello world') + statistics_dump) model_sender_node.start( callback=fetch_model) diff --git a/amlip_py/test/manual/model_sender_str_listener.py b/amlip_py/test/manual/model_sender_str_listener.py index df41dac3..7a8c59e1 100644 --- a/amlip_py/test/manual/model_sender_str_listener.py +++ b/amlip_py/test/manual/model_sender_str_listener.py @@ -12,12 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. +import pickle as pkl + from py_utils.wait.BooleanWaitHandler import BooleanWaitHandler from amlip_py.node.ModelManagerSenderNode import ModelManagerSenderNode, ModelReplierLambda from amlip_py.types.AmlipIdDataType import AmlipIdDataType -from amlip_py.types.ModelDataType import ModelDataType -from amlip_py.types.ModelSolutionDataType import ModelSolutionDataType +from amlip_py.types.ModelReplyDataType import ModelReplyDataType +from amlip_py.types.ModelRequestDataType import ModelRequestDataType # Domain ID DOMAIN_ID = 166 @@ -27,15 +29,21 @@ def fetch_model( - model: ModelDataType) -> ModelSolutionDataType: - solution = ModelSolutionDataType(model.to_string().upper()) - print(f'Model request received from client\n' - f' model: {model.to_string()}\n' - f' solution: {solution.to_string()}') + request: ModelRequestDataType) -> ModelReplyDataType: + + print('Request received:\n') + print(request.to_string()) + print('\n') + + reply = ModelReplyDataType(request.to_string().upper()) waiter.open() - return solution + print('Publish reply:\n') + print(request.to_string().upper()) + print('\n') + + return reply def main(): @@ -53,9 +61,20 @@ def main(): print(f'Node created: {model_sender_node.get_id()}. ' 'Already processing models.') - model_sender_node.update_statistics( + data = { + 'name': 'hello world', + 'size': 56 + } + + statistics_dump = pkl.dumps(data) + + print('\n\nPublish statistics: \n') + print(data) + print('\n') + + model_sender_node.publish_statistics( 'ModelManagerSenderStatistics', - 'hello world') + statistics_dump) model_sender_node.start( listener=ModelReplierLambda(fetch_model)) diff --git a/amlip_swig/src/swig/amlip_swig.i b/amlip_swig/src/swig/amlip_swig.i index 0623a397..46cef729 100644 --- a/amlip_swig/src/swig/amlip_swig.i +++ b/amlip_swig/src/swig/amlip_swig.i @@ -87,8 +87,8 @@ typedef unsigned long uint64_t; %include "amlip_swig/types/job/JobSolutionDataType.i" %include "amlip_swig/types/inference/InferenceDataType.i" %include "amlip_swig/types/inference/InferenceSolutionDataType.i" -%include "amlip_swig/types/model/ModelDataType.i" -%include "amlip_swig/types/model/ModelSolutionDataType.i" +%include "amlip_swig/types/model/ModelRequestDataType.i" +%include "amlip_swig/types/model/ModelReplyDataType.i" %include "amlip_swig/types/model/ModelStatisticsDataType.i" // node diff --git a/amlip_swig/src/swig/amlip_swig/types/model/ModelDataType.i b/amlip_swig/src/swig/amlip_swig/types/model/ModelReplyDataType.i similarity index 79% rename from amlip_swig/src/swig/amlip_swig/types/model/ModelDataType.i rename to amlip_swig/src/swig/amlip_swig/types/model/ModelReplyDataType.i index 3d84d2c1..3754a4a1 100644 --- a/amlip_swig/src/swig/amlip_swig/types/model/ModelDataType.i +++ b/amlip_swig/src/swig/amlip_swig/types/model/ModelReplyDataType.i @@ -13,7 +13,7 @@ // limitations under the License. //////////////////////////////////////////////////////// -// Binding for class ModelDataType +// Binding for class ModelReplyDataType //////////////////////////////////////////////////////// // Import parent class @@ -24,14 +24,14 @@ %ignore *::operator=; %{ -#include +#include -using ModelDataType = eprosima::amlip::types::ModelDataType; +using ModelReplyDataType = eprosima::amlip::types::ModelReplyDataType; %} // Include the class interfaces -%include +%include %pythoncode %{ -ModelDataType = GenericDataType +ModelReplyDataType = GenericDataType %} diff --git a/amlip_swig/src/swig/amlip_swig/types/model/ModelSolutionDataType.i b/amlip_swig/src/swig/amlip_swig/types/model/ModelRequestDataType.i similarity index 78% rename from amlip_swig/src/swig/amlip_swig/types/model/ModelSolutionDataType.i rename to amlip_swig/src/swig/amlip_swig/types/model/ModelRequestDataType.i index 1f297caf..6843d1ed 100644 --- a/amlip_swig/src/swig/amlip_swig/types/model/ModelSolutionDataType.i +++ b/amlip_swig/src/swig/amlip_swig/types/model/ModelRequestDataType.i @@ -13,7 +13,7 @@ // limitations under the License. //////////////////////////////////////////////////////// -// Binding for class ModelSolutionDataType +// Binding for class ModelRequestDataType //////////////////////////////////////////////////////// // Import parent class @@ -24,14 +24,14 @@ %ignore *::operator=; %{ -#include +#include -using ModelSolutionDataType = eprosima::amlip::types::ModelSolutionDataType; +using ModelRequestDataType = eprosima::amlip::types::ModelRequestDataType; %} // Include the class interfaces -%include +%include %pythoncode %{ -ModelSolutionDataType = GenericDataType +ModelRequestDataType = GenericDataType %} diff --git a/amlip_swig/src/swig/amlip_swig/types/model/ModelStatisticsDataType.i b/amlip_swig/src/swig/amlip_swig/types/model/ModelStatisticsDataType.i index 1bbf77af..ae4c7730 100644 --- a/amlip_swig/src/swig/amlip_swig/types/model/ModelStatisticsDataType.i +++ b/amlip_swig/src/swig/amlip_swig/types/model/ModelStatisticsDataType.i @@ -32,10 +32,17 @@ namespace std { %ignore eprosima::amlip::types::ModelStatisticsDataType::ModelStatisticsDataType(ModelStatisticsDataType&&); %ignore eprosima::amlip::types::operator <<(std::ostream &,const ModelStatisticsDataType&); +// Declare the to string method +%extend eprosima::amlip::types::ModelStatisticsDataType { + std::string __str__() const + { + return $self->to_string(); + } +} + %{ #include -using ModelStatisticsDataType = eprosima::amlip::types::ModelStatisticsDataType; %} // Include the class interfaces diff --git a/tools/agent_tool/README.md b/tools/agent_tool/README.md index ef121b38..4717e338 100644 --- a/tools/agent_tool/README.md +++ b/tools/agent_tool/README.md @@ -17,19 +17,19 @@ In order to know all the possible arguments supported by this tool, use the command: ```sh - ./agent tool -h + amlip_agent -h ``` To launch an Agent Server Node, execute: ```sh - ./agent tool -e server -l 87.216.115.84 -q 18000 -t tcp + amlip_agent -e server -l 87.216.115.84 -q 18000 -t tcp ``` To launch an Agent Client Node, execute: ```sh - ./agent_tool -e client -c 87.216.115.84 -p 18000 -t tcp + amlip_agent -e client -c 87.216.115.84 -p 18000 -t tcp ``` ## Arguments @@ -53,7 +53,7 @@ General options: Client options: -n, --name - Name (Default: agent_tool). + Name (Default: amlip_agent). -d, --domain DDS domain ID (Default: 0). -c, --connection-address
diff --git a/tools/agent_tool/package.xml b/tools/agent_tool/package.xml index 95bc5a16..b43637da 100644 --- a/tools/agent_tool/package.xml +++ b/tools/agent_tool/package.xml @@ -1,7 +1,7 @@ - amlip_agent_tool + amlip_agent 0.1.0 *eprosima AML-IP* C++ application to execute an agent. diff --git a/tools/agent_tool/project_settings.cmake b/tools/agent_tool/project_settings.cmake index 8e9e34f9..dc0d20fd 100644 --- a/tools/agent_tool/project_settings.cmake +++ b/tools/agent_tool/project_settings.cmake @@ -13,11 +13,11 @@ # limitations under the License. ############################################################################### -# Set settings for project fastddsspy_tool +# Set settings for project agent_tool ############################################################################### set(MODULE_NAME - amlip_agent_tool) + amlip_agent) set(MODULE_SUMMARY "C++ application to execute an agent.") @@ -48,7 +48,7 @@ set(MODULE_VERSION_FILE_PATH "../../VERSION") set(MODULE_TARGET_NAME - "agent_tool") + "amlip_agent") set(MODULE_CPP_VERSION C++14) diff --git a/tools/agent_tool/src/cpp/main.cpp b/tools/agent_tool/src/cpp/main.cpp index 515c4f33..de68f79e 100644 --- a/tools/agent_tool/src/cpp/main.cpp +++ b/tools/agent_tool/src/cpp/main.cpp @@ -13,7 +13,7 @@ // limitations under the License. /** - * @file agent_tool.cpp + * @file main.cpp * */ @@ -70,7 +70,7 @@ int main( int connection_port = 12121; int listening_port = 12121; int port = 12121; - std::string name = "agent_tool"; + std::string name = "amlip_agent"; eprosima::ddspipe::participants::types::TransportProtocol transport_protocol = eprosima::ddspipe::participants::types::TransportProtocol::udp; diff --git a/tools/agent_tool/src/cpp/user_interface/arguments_configuration.h b/tools/agent_tool/src/cpp/user_interface/arguments_configuration.h index 06d5ea80..ccc48d14 100644 --- a/tools/agent_tool/src/cpp/user_interface/arguments_configuration.h +++ b/tools/agent_tool/src/cpp/user_interface/arguments_configuration.h @@ -17,8 +17,8 @@ * */ -#ifndef EPROSIMA_AGENT_TOOL_USERINTERFACE_ARG_CONFIGURATION_H_ -#define EPROSIMA_AGENT_TOOL_USERINTERFACE_ARG_CONFIGURATION_H_ +#ifndef EPROSIMA_AMLIP_AGENT_USERINTERFACE_ARG_CONFIGURATION_H_ +#define EPROSIMA_AMLIP_AGENT_USERINTERFACE_ARG_CONFIGURATION_H_ #include #include @@ -182,7 +182,7 @@ const option::Descriptor usage[] = { /// CLIENT OPTIONS {UNKNOWN_OPT, 0, "", "", Arg::None, "\nClient options:"}, { NAME, 0, "n", "name", Arg::String, - " -n, --name \t Name (Default: agent_tool)." }, + " -n, --name \t Name (Default: amlip_agent)." }, { DOMAIN_ID, 0, "d", "domain", Arg::Numeric, " -d, --domain \tDDS domain ID (Default: 0)." }, { CONNECTION_ADDRESS, 0, "c", "connection-address", Arg::String, @@ -191,7 +191,7 @@ const option::Descriptor usage[] = { " -p, --connection-port \tAddress connection port (Default: 12121)." }, { TRANSPORT, 0, "t", "transport", Arg::Transport, " -t, --transport \tUse only TCPv4 or UDPv4 transport. (Default: TCPv4)." }, - { 0, 0, 0, 0, 0, 0 }, + /// SERVER OPTIONS {UNKNOWN_OPT, 0, "", "", Arg::None, "\nServer options:"}, { NAME, 0, "n", "name", Arg::String, @@ -204,7 +204,7 @@ const option::Descriptor usage[] = { " -q, --listening-port \tAddress listening port (Default: 12121)." }, { TRANSPORT, 0, "t", "transport", Arg::Transport, " -t, --transport \tUse only TCPv4 or UDPv4 transport. (Default: TCPv4)." }, - { 0, 0, 0, 0, 0, 0 }, + /// REPEATER OPTIONS {UNKNOWN_OPT, 0, "", "", Arg::None, "\nRepeater options:"}, { NAME, 0, "n", "name", Arg::String, @@ -221,6 +221,7 @@ const option::Descriptor usage[] = { " -q, --listening-port \tAddress listening port (Default: 12121)." }, { TRANSPORT, 0, "t", "transport", Arg::Transport, " -t, --transport \tUse only TCPv4 or UDPv4 transport. (Default: TCPv4)." }, + { 0, 0, 0, 0, 0, 0 } }; @@ -231,4 +232,4 @@ void print_warning( std::cerr << "WARNING: " << opt << " is a " << type << " option, ignoring argument." << std::endl; } -#endif /* EPROSIMA_AGENT_TOOL_USERINTERFACE_ARG_CONFIGURATION_H_ */ +#endif /* EPROSIMA_AMLIP_AGENT_USERINTERFACE_ARG_CONFIGURATION_H_ */