Я спрашиваю вас, есть ли способ иметь приоритет между двумя узлами ROS. В частности, у меня есть узел ROS, который выводит текстовый файл с 60 данными в нем, и он воссоздает его каждый раз, потому что данные меняются. Затем у меня есть узел, который должен анализировать этот текстовый файл. По сути, мне нужно внести некоторые изменения, чтобы иметь механизм, который останавливает узел анализатора, когда узел записи работает, а затем он должен отправить сигнал узлу анализатора, чтобы он мог запускать и анализировать текстовый файл. И затем узел записи должен вернуть, скажем, «ответственный», чтобы снова перезаписать текстовый файл. Итак, простыми словами, это петля. Кто-то сказал мне, что возможным решением может быть что-то вроде темы «семафор», в которой узел записи записывает, например, логическое значение 1, когда выполняет открытие, запись и закрытие текстового файла, поэтому анализатор узел знает, что не может заниматься своей разработкой, так как файл еще не готов. И, когда писатель закончил и закрыл текстовый файл, он должен быть опубликован со значением 0, которое разрешает анализ узлу анализатора. Я искал публикацию логических значений и нашел код, который может быть примерно таким:
ros::Publisher pub = n.advertise<std_msgs::Bool>("semaphore", 1000);
std_msgs::Bool state;
state.data = 1;
Я не знаю, нужно ли мне использовать только издателя в узле записи и подписчика в узле анализатора. Возможно, мне придется использовать оба из них в двух узлах, что-то вроде: писатель поместил 1 в семафор темы, чтобы анализатор знал, что не может получить доступ к текстовому файлу, создает текстовый файл, а затем помещает 0 в тему и подписывается на тема снова ждет 1; анализатор делает нечто подобное, но в обратном порядке. Я поместил два кода ниже, потому что понятия не имею, где разместить издателя и подписчика и как заставить их работать хорошо. Если возможно, я должен сохранить эту структуру рабочего потока в своих кодах. ПРИМЕЧАНИЕ: новый текстовый файл создается почти каждые 10 секунд, поскольку в текстовый файл записываются данные, поступающие из другой темы ROS, а код в модуле записи имеет механизм для выполнения такого рода уточнений. Заранее спасибо!!! РЕДАКТИРОВАТЬ: Теперь коды исправлены с помощью решения на основе темы, как я объясняю в своем последнем комментарии.
Код писателя:
#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;
}