Как определить, что type_name удаленного DataWriter, используя RTI DDS

Я пишу инструмент на c ++ с использованием RTI DDS 5.2, который должен определять, когда DataWriters удаляются, и знать, type_name связанных данных. Я использую код, похожий на этот а также этот.

Я использую DDSWaitSet и он срабатывает, когда DataWriter удаляется с delete_datawriter но SampleInfo указывает, что данные недействительны и, конечно же, образец данных type_name пустой.

Есть ли способ удалить DataWriter таким образом, чтобы заставить встроенную тему подписки получить type_name? Или есть настройка QOS, которую я могу установить, чтобы исправить это поведение?

0

Решение

Нашел обходной путь для этой проблемы. Я до сих пор не знаю, как сделать так, чтобы образец данных действовал, когда DataWriter ушел, но SampleInfo действительно есть поле instance_state который однозначно идентифицирует писателя. Решение состоит в том, чтобы отслеживать type_names когда данные действительны, и просто посмотрите, когда это не так. Вот суть кода, который я использую для решения этой проблемы:

struct cmp_instance_handle {
bool operator()(const DDS_InstanceHandle_t& a, const DDS_InstanceHandle_t& b) const {
return !DDS_InstanceHandle_equals(&a, &b);
}
};

void wait_for_data_writer_samples()
{
ConditionSeq cs;
DDSWaitSet* ws = new DDSWaitSet();
StatusCondition* condition = _publication_dr->get_statuscondition();
DDS_Duration_t timeout = {DDS_DURATION_INFINITE_SEC, DDS_DURATION_INFINITE_NSEC};
std::map<DDS_InstanceHandle_t, std::string, cmp_instance_handle> instance_handle_map;

ws->attach_condition(condition);
condition->set_enabled_statuses(DDS_STATUS_MASK_ALL);

while(true) {
ws->wait(cs, timeout);

PublicationBuiltinTopicDataSeq data_seq;
SampleInfoSeq info_seq;

_publication_dr->take(
data_seq,
info_seq,
DDS_LENGTH_UNLIMITED,
ANY_SAMPLE_STATE,
ANY_VIEW_STATE,
ANY_INSTANCE_STATE
);

int len = data_seq.length();
for(int i = 0; i < len; ++i) {
DDS_InstanceHandle_t instance_handle = info_seq[i].instance_handle;

if(info_seq[i].valid_data) {
std::string type_name(data_seq[i].type_name);

// store the type_name in the map for future use
instance_handle_map[instance_handle] = type_name;
if(info_seq[i].instance_state == DDS_InstanceStateKind::DDS_ALIVE_INSTANCE_STATE) {
do_data_writer_alive_callback(type_name);
}
else {
// If the data is valid, but not DDS_ALIVE_INSTANCE_STATE, the DataWriter died *and* we can
// directly access the type_name so we can handle that case here
do_data_writer_dead_callback(type_name);
}
}
else {
// If the data is not valid then the DataWriter is definitely not alive but we can't directly access
// the type_name. Fortunately we can look it up in our map.
do_data_writer_dead_callback(instance_handle_map[instance_handle]);

// at this point the DataWriter is gone so we remove it from the map.
instance_handle_map.erase(instance_handle);

}
}
_publication_dr->return_loan(data_seq, info_seq);
}
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]