Marcofon Marcofon - 7 months ago 41
C++ Question

I want to publish in a ROS topic floating numbers from a text file

I'm trying to read a text file which contains many floating numbers in one column, as in this example:

0.872
0.876
0.880
0.888
0.900


In particular I want to read it line by line and for every time that a line is read I want that this numerical value is stored in a variable that has to be published on a ROS topic with a wait time of about 1 second and then it has to do it again until the end of the file.
I'm trying to write my question in a step-by-step way to be (maybe) more clear:


  1. Read the first line (for ex. 0.872)

  2. Save the number 0.872 in a variable

  3. Publish that variable that has only 0.872 as a value in a ROS topic

  4. Wait for a second

  5. Repeat the loop until the end of file.



With some searching around the web and here on Stack Overflow, I wrote a code that, for now, prints the numbers on the terminal (even if it's not what I want), since I don't know how to implement the ROS commands for publishing although I've read the tutorials.
But some numbers appear to be cut like this:

0.876

0.88

0.888

0.9

0.9

0.876

0.904

0.908

0.88


Instead of being equal in precision to the other numbers.
Here is the code that I wrote it for now:

#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;

int main()
{
ifstream inputFile("/home/marco/Scrivania/marks.txt");
string line;

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

ss >> heart;
cout << heart << endl << endl;
}


NOTE: It is written in plain C++ language without any ROS commands like ROS init, etc. So, if you can would be great if you can tell me also how to do it, since I've only made one node of ROS so far.

EDIT: With the modifications suggested when put in a ROS node, compiled and executed, it runs with no problems.
Then i tried to add the topic part, with no success. I update the code below:

#include "ros/ros.h"
#include "std_msgs/Float32.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;


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

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

float heart;

ss >> heart;

//std::cout << std::fixed << std::setprecision(3) << heart << endl << endl;
}

ros::Publisher HeartRateInterval_pub = n.advertise<std_msgs::Float32>("HeartRateInterval", 1000);

ros::Rate loop_rate(1);

int count = 0;
while (ros::ok())
{

std_msgs::Float32 msg;

std::stringstream ss;
ss << std::cout << std::fixed << std::setprecision(3) << heart << endl << endl << count;
msg.data = ss.str();

HeartRateInterval_pub.publish(msg)

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

ros::spinOnce();

loop_rate.sleep();

++count;
}

return 0;

}

Answer

This is the code i obtained after a lot of struggle and a good amount of luck! It does what i want, the only little problem is that i can close the ROS node using Ctrl+c. Any suggestions would be more than appreciated. Thank you very much guys for all your advices and help!

Code:

#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();

pub.publish(msg);

ros::spinOnce();

loop_rate.sleep();

}

}

return 0;

}