Я спрашиваю вас, есть ли способ иметь приоритет между двумя узлами ROS. В частности, у меня есть узел ROS, который делает вывод, который представляет собой текстовый файл с 60 данными в нем, и он обновляет его каждый раз, потому что данные изменяются. Тогда у меня есть узел, который должен проанализировать этот текстовый файл. В принципе, мне нужно внести некоторые изменения в механизм, который останавливает узел анализатора при запуске узла записи, тогда он должен отправить сигнал узлу анализатора, чтобы он мог запускать и анализировать текстовый файл. И тогда узел-писатель должен вернуться, скажем, «ответственный», чтобы снова перезаписать текстовый файл. Итак, простыми словами, это цикл. Кто-то сказал мне, что возможное решение может быть чем-то вроде темы «семафора», в которой узел-писатель пишет, например, логическое значение 1, когда делает открытие, запись и закрытие текстового файла, поэтому анализатор узел знает, что не может выполнить свою разработку, так как файл еще не готов. И, когда автор закончил и закрыл текстовый файл, ему должно быть опубликовано значение 0, которое разрешает анализ узлом анализатора. Я искал публикацию логических значений и я нашел код, который может быть что-то вроде этого:Есть ли способ иметь приоритет между двумя ROS-узлами?
ros::Publisher pub = n.advertise<std_msgs::Bool>("semaphore", 1000);
std_msgs::Bool state;
state.data = 1;
Я не знаю, если я только использовать издатель в узле писателя и абонент в анализаторе узел. Может быть, мне нужно использовать оба из них в двух узлах, что-то вроде: writer помещает 1 в семафор темы, поэтому анализатор знает, что не может получить доступ к текстовому файлу, делает текстовый файл, а затем помещает 0 в тему и подписывается на тема снова ждет 1; анализатор делает что-то подобное, но наоборот. Я поставил два кода ниже, потому что я не знаю, где разместить издателя и подписчика, и как заставить их работать хорошо. Если возможно, мне нужно сохранить эту структуру рабочего потока в моих кодах. ПРИМЕЧАНИЕ: новый текстовый файл создается почти каждые 10 секунд, так как в текстовом файле записываются данные, поступающие из другой темы ROS, а в коде у писателя есть механизм для такого рода разработки. Спасибо заранее! EDIT: теперь коды исправлены с помощью решения на основе темы, как я объясняю в своем последнем комментарии.
код Автор:
#include "ros/ros.h"
#include "std_msgs/String.h"
#include "std_msgs/Bool.h"
#include "../include/heart_rate_monitor/wfdb.h"
#include <stdio.h>
#include <sstream>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <algorithm>
#include <deque>
#include "heart_rate_monitor/analyse_heart_rate.h"
using namespace std;
static std::deque<std::string> queue_buffer;
static int entries_added_since_last_write = 0;
ros::Publisher pub;
void write_data_to_file()
{
// open file;
std::ofstream data_file("/home/marco/catkin_ws/src/heart_rate_monitor/my_data_file.txt");
if (data_file.is_open())
{
for (int i = 0; i < queue_buffer.size(); ++i)
{
data_file << queue_buffer[i] << std::endl;
}
}
else
{
std::cout << "Error - Cannot open file." << std::endl;
exit(1);
}
data_file.close();
std_msgs::Bool state;
state.data = 0;
pub.publish(state);
}
void process_message(const std_msgs::String::ConstPtr& string_msg)
{
std_msgs::Bool state;
state.data = 1;
pub.publish(state);
// if buffer has already 60 entries, throw away the oldest one
if (queue_buffer.size() == 60)
{
queue_buffer.pop_front();
}
// add the new data at the end
queue_buffer.push_back(string_msg->data);
// check if 10 elements have been added and write to file if so
entries_added_since_last_write++;
if (entries_added_since_last_write >= 10
&& queue_buffer.size() == 60)
{
// write data to file and reset counter
write_data_to_file();
entries_added_since_last_write = 0;
}
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "writer");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("/HeartRateInterval", 1000, process_message);
pub = n.advertise<std_msgs::Bool>("/semaphore", 1000);
ros::spin();
return 0;
}
анализатор кода:
#include "ros/ros.h"
#include "std_msgs/String.h"
#include "std_msgs/Bool.h"
#include "../include/heart_rate_monitor/wfdb.h"
#include <stdio.h>
#include <sstream>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <algorithm>
#include <deque>
#include "heart_rate_monitor/analyse_heart_rate.h"
void orderCallback(const std_msgs::Bool::ConstPtr& msg)
{
if (msg->data == 0)
{
chdir("/home/marco/catkin_ws/src/heart_rate_monitor");
system("get_hrv -R my_data_file.txt >doc.txt");
}
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "analyzer");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("/semaphore", 1000, orderCallback);
ros::spin();
return 0;
}
Здравствуйте @Vtik, спасибо вам за ваш ответ! Не возражаете, если я попрошу вас подробно объяснить вашу идею? Также очень понравились бы фрагменты кода. Только если вы можете, конечно! Я говорю это, потому что я очень новичок в кодировании и супер новичок в ROS. Еще раз спасибо! – Marcofon
Спасибо вам большое! Я постараюсь применить его к моему делу! Еще раз спасибо! Я дам вам знать, смогу ли я это сделать. – Marcofon
Прошу прощения за глупый вопрос, но в файле .srv вместо имени файла я должен указать имя текстового файла, который я хочу проанализировать. EDIT: И еще одна вещь. Со структурой, которую вы мне предложили, называется ли сценарий каждый раз или только когда у меня есть 10 новых данных в текстовом файле с 60 данными в нем? Поскольку это моя цель, может быть, это было непонятно из моего вопроса и моих кодов, я попытался объяснить это в разделе NOTE. Прошу прощения, если это так! – Marcofon