I have some problems with a program that have to print data on a text file

I'm sorry if this question is too simple for you, but i don't have good programming skills and ROS knowledge. I have a ROS topic in which are published some numbers that are heart beat intervals in seconds. I need to subscribe to that topic and do this kind of elaboration: The idea is to have a little array of ten numbers in which i can store continuously ten heart beat. Then i have a bigger array of 60 numbers that must go up by ten position in order to have at the bottom the newest ten values of the small array and it has to "throw away" the ten oldest values ( i did a bit of research and maybe i have to use a vector instead of an array because in C++ array are fixed as far as i read ). Then i have to print every time these 60 values in a text file (i mean in a loop, so the the text file will be continuously overwritten). Moreover, i see that ROS outputs the data from a topic in this manner: data: 0.987 with every data divided from the others by --- in a column. What i really want, because i need it for a script that reads text file in this manner, is a text file in which the values are in one column without spaces and other signs or words, like this:

0.404
0.952
0.956
0.940
0.960

I know that this question is related to some "special" use of the C++ but, as you will see from the codes below, is almost a pure C++ code.
For now, with some good help of two guys over the web, i have done a code for the subscriber that creates the text file, but doesn't write nothing into it.
I will provide both codes, publisher and subscriber.
Thank you in advance!
Last edited on
This is the code for the subscriber, in which i have my problems:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
 

#include "ros/ros.h"
#include "std_msgs/String.h"
#include "../include/heart_rate_monitor/wfdb.h"
#include <stdio.h>
#include <sstream>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <algorithm>
#include <deque>

using namespace std;

std::ofstream data_file("/home/marco/catkin_ws/src/heart_rate_monitor/my_data_file.txt");

static std::deque<std::string> queue_buffer;
static int entries_added_since_last_write = 0;

void write_data_to_file()
{
  // open file
  
  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();
}

void process_message(const std_msgs::String::ConstPtr& string_msg)
{
  // 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);

  
  ros::spin();

  return 0;
}



This is the code of the publisher, and it works:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include "ros/ros.h"
#include "std_msgs/String.h"
#include "../include/heart_rate_monitor/wfdb.h"
#include <stdio.h>
#include <sstream>
#include <iostream>
#include <fstream>
#include <iomanip>

using namespace std;


int main(int argc, char **argv)
{
  
  ros::init(argc, argv, "heart_rate_monitor");

  ros::NodeHandle n;

  ros::Publisher pub = n.advertise<std_msgs::String>("/HeartRateInterval", 1000);

  ros::Rate loop_rate(1);
  
  while (ros::ok())

{ 

  ifstream inputFile("/home/marco/Scrivania/marks.txt");

  string line;

  while (getline(inputFile, line)) {
  
  
  istringstream ss(line);

  string heart;

  ss >> heart;

  std_msgs::String msg;

  msg.data = ss.str();

  //ROS_INFO("%s", msg.data.c_str());

  pub.publish(msg);

  ros::spinOnce();

  loop_rate.sleep();

  }

}
    
  return 0;

}

UPDATE: I solved the problem! The program didn't enter in the second if of the process_message function because in the beginning the buffer of 60 numbers was empty and the double condition would never become true. So i simply changed the ==10 with >=10. Thank you for your help!!
Topic archived. No new replies allowed.