235 lines
7.2 KiB
C++
Executable File
235 lines
7.2 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
*
|
|
* TopicData
|
|
* Uses DTC to subscribe to data
|
|
*
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
*/
|
|
|
|
#include "topic_data.h"
|
|
#include <NGLLogger/NGLLoggerBootstrap.h>
|
|
|
|
#include <ExerciseManagement/exm.hpp>
|
|
|
|
namespace DataSampleReceiver
|
|
{
|
|
|
|
TopicData::TopicData(const dds::domain::DomainParticipant &dp, const std::string &partition, const QVector<DDSGeneric::TopicDescription> &vDdro)
|
|
: DDSConnector::Subscriber(dp, partition)
|
|
, m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("DSR.TopicData"))
|
|
{
|
|
initDDTCs(vDdro);
|
|
}
|
|
|
|
TopicData::~TopicData()
|
|
{
|
|
qDeleteAll(m_ddtcMap);
|
|
m_ddtcMap.clear();
|
|
}
|
|
|
|
bool TopicData::initDDTCs(const QVector<DDSGeneric::TopicDescription> &vDdro)
|
|
{
|
|
if (m_domainParticipant == nullptr ||
|
|
m_ddsSubscriber == nullptr ||
|
|
m_subscriberListener == nullptr)
|
|
{
|
|
ERROR_LOG(m_logger) << "Inititialisation failed: "
|
|
" m_domainParticipant/m_ddsSubscriber/m_subscriberListener not initialised";
|
|
return false;
|
|
}
|
|
|
|
m_vDdro = vDdro;
|
|
|
|
INFO_LOG(m_logger) << "TopicDescriptions size: #" << vDdro.size();
|
|
|
|
// Initialise DDTCs
|
|
for (const DDSGeneric::TopicDescription &topicDesc : vDdro)
|
|
{
|
|
INFO_LOG(m_logger) << "topicDesc.topicName: " << topicDesc.name;
|
|
INFO_LOG(m_logger) << "topicDesc.topicType: " << topicDesc.typeName;
|
|
|
|
DTC::Ddtc<DDSGeneric::DynamicDataReader>* ddtc = this->create(
|
|
[this](const dds::core::xtypes::DynamicData& data, const std::string &topicName, DataModification modType)
|
|
{ Q_UNUSED(modType); processData(data, QString::fromStdString(topicName)); },
|
|
topicDesc.type,
|
|
nullptr /* Use SubscriberListener from DdsConnector */,
|
|
topicDesc.name );
|
|
|
|
if (ddtc == nullptr)
|
|
{
|
|
ERROR_LOG(m_logger) << "Can't create ddtc for Topic (" << topicDesc.name
|
|
<< "), TypeName (" << topicDesc.typeName << ")";
|
|
continue;
|
|
}
|
|
|
|
m_ddtcMap.insert(topicDesc.name, ddtc);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void TopicData::processData(const ExerciseManagement::Exercise &data)
|
|
{
|
|
|
|
DEBUG_LOG(m_logger) << "=> IN processData Exercise";
|
|
|
|
INFO_LOG(m_logger) << "|#| id: # " << data.id();
|
|
INFO_LOG(m_logger) << "|#| name: # " << data.name();
|
|
INFO_LOG(m_logger) << "|#| state: # " << data.state();
|
|
INFO_LOG(m_logger) << "|#| partition: # " << data.partitionName();
|
|
INFO_LOG(m_logger) << "|#| isUsed: # " << data.isUsed();
|
|
INFO_LOG(m_logger) << "|#| markedAsDeleted: # " << data.isDeleted();
|
|
|
|
}
|
|
|
|
|
|
void TopicData::processData(const ParticipantManagement::Participant &data)
|
|
{
|
|
DEBUG_LOG(m_logger) << "-> IN processData Participant";
|
|
|
|
INFO_LOG(m_logger) << "|#| participantId: #" << data.id();
|
|
INFO_LOG(m_logger) << "|#| name: #" << data.name();
|
|
INFO_LOG(m_logger) << "|#| hierarchyNo: #" << data.hierarchyNumber();
|
|
INFO_LOG(m_logger) << "|#| equipNo: #" << data.equipmentNumber();
|
|
|
|
//processData(data.location());
|
|
}
|
|
|
|
bool TopicData::processData(const dds::core::xtypes::DynamicData &data, const QString &ns)
|
|
{
|
|
DEBUG_LOG(m_logger) << "-> IN processData dynamicData";
|
|
if (tryProcessDataAsTyped(data, ns))
|
|
return true;
|
|
|
|
// maybe also possible;
|
|
// getStructType() from ddtc (m_ddtcMap)
|
|
|
|
// If no Namespace (thus, external call) or no valid data: Create new DynData
|
|
//if ( data.type().kind() == dds::core::xtypes::TypeKind::NO_TYPE )
|
|
// data = dds::core::xtypes::DynamicData(*m_type);
|
|
|
|
// data[n] runs from 1..count()!
|
|
for (uint32_t member_index = 1; member_index <= data.member_count(); ++member_index)
|
|
{
|
|
const rti::core::xtypes::DynamicDataMemberInfo info = data.member_info(member_index);
|
|
|
|
INFO_LOG(m_logger) << "Parameter: " << info.member_name();
|
|
TRACE_LOG(m_logger) << "MemberName: " << ns << " - " << info.member_name();
|
|
TRACE_LOG(m_logger) << "member_id = " << info.member_index()
|
|
<< ", member_kind = " << info.member_kind()
|
|
<< ", index: " << data.member_index(info.member_name());
|
|
|
|
// if (!data.member_exists(member_index))
|
|
// continue;
|
|
|
|
QVariant var;
|
|
switch(info.member_kind().underlying())
|
|
{
|
|
case dds::core::xtypes::TypeKind::CHAR_8_TYPE:
|
|
var = data.value<char>(member_index);
|
|
break;
|
|
#if RTI_DDS_VERSION_MAJOR < 6
|
|
case dds::core::xtypes::TypeKind::CHAR_32_TYPE:
|
|
#else
|
|
case dds::core::xtypes::TypeKind::CHAR_16_TYPE:
|
|
#endif
|
|
var = data.value<DDS_Wchar>(member_index);
|
|
break;
|
|
case dds::core::xtypes::TypeKind::UINT_8_TYPE:
|
|
var = data.value<uint8_t>(member_index);
|
|
break;
|
|
case dds::core::xtypes::TypeKind::INT_16_TYPE:
|
|
var = data.value<int16_t>(member_index);
|
|
break;
|
|
case dds::core::xtypes::TypeKind::UINT_16_TYPE:
|
|
var = data.value<uint16_t>(member_index);
|
|
break;
|
|
case dds::core::xtypes::TypeKind::INT_32_TYPE:
|
|
var = data.value<int32_t>(member_index);
|
|
break;
|
|
case dds::core::xtypes::TypeKind::UINT_32_TYPE:
|
|
var = data.value<uint32_t>(member_index);
|
|
break;
|
|
case dds::core::xtypes::TypeKind::INT_64_TYPE:
|
|
var = data.value<qlonglong>(member_index);
|
|
break;
|
|
case dds::core::xtypes::TypeKind::UINT_64_TYPE:
|
|
var = data.value<qulonglong>(member_index);
|
|
break;
|
|
case dds::core::xtypes::TypeKind::FLOAT_32_TYPE:
|
|
var = data.value<float>(member_index);
|
|
break;
|
|
case dds::core::xtypes::TypeKind::FLOAT_64_TYPE:
|
|
var = data.value<double>(member_index);
|
|
break;
|
|
case dds::core::xtypes::TypeKind::ENUMERATION_TYPE:
|
|
var = data.value<int32_t>(member_index);
|
|
break;
|
|
case dds::core::xtypes::TypeKind::BOOLEAN_TYPE:
|
|
var = data.value<bool>(member_index);
|
|
break;
|
|
case dds::core::xtypes::TypeKind::STRING_TYPE:
|
|
{
|
|
const dds::core::string tmp = data.value<dds::core::string>(member_index);
|
|
if (tmp.c_str()) // unset -> nullptr
|
|
var = QString::fromUtf8(tmp.c_str ());
|
|
break;
|
|
}
|
|
case dds::core::xtypes::TypeKind::STRUCTURE_TYPE:
|
|
{
|
|
// rti::core::xtypes::LoanedDynamicData innerLoaned = data.loan_value(member_index);
|
|
processData(data.value<dds::core::xtypes::DynamicData>(member_index), ns + QString::fromStdString(info.member_name()) + QLatin1Char('.'));
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
INFO_LOG(m_logger) << "Content : '" << var.toString() << "'";
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool TopicData::tryProcessDataAsTyped(const dds::core::xtypes::DynamicData &data, const QString &ns)
|
|
{
|
|
// ExerciseManagement::Exercise
|
|
if (processData<ExerciseManagement::Exercise>(data,ns))
|
|
return true;
|
|
|
|
// Core::SpatialData
|
|
if (processData<ParticipantManagement::Participant>(data,ns))
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @brief Get the typeCode of a topic if available in m_vddro
|
|
* @param topicName
|
|
* @return
|
|
*/
|
|
dds::core::xtypes::StructType TopicData::getTypeCode(const std::string &topicName) const
|
|
{
|
|
DEBUG_LOG(m_logger) << "m_vDdro.size = " << m_vDdro.size();
|
|
|
|
for (int i = 0; i < m_vDdro.size(); ++i)
|
|
{
|
|
DDSGeneric::TopicDescription td = m_vDdro.at(i);
|
|
if (td.name == topicName)
|
|
{
|
|
INFO_LOG(m_logger) << "Found topicType for #" << topicName;
|
|
return td.type;
|
|
}
|
|
}
|
|
|
|
// TODO: oder besser throw?
|
|
return dds::core::xtypes::StructType("Unknown");
|
|
}
|
|
|
|
|
|
} // Namespace DataSampleReceiver
|