0

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;

}
Marcofon
  • 49
  • 2
  • 12
  • Just curious: what is a ROS topic? – Rudy Velthuis Nov 14 '16 at 14:44
  • Let's call it "a space" where the ROS nodes (that are basically executables) can publish and read messages for the communication between them. – Marcofon Nov 14 '16 at 14:54
  • thanks, that is clearer now. – Rudy Velthuis Nov 14 '16 at 15:16
  • @RudyVelthuis no problem! :) – Marcofon Nov 14 '16 at 15:24
  • Trailing zeros after the comma don't make any difference (i.e. `0.9 == 0.900`). It is only a question of formatting when printing them. So regarding the values of the numbers they are not cut. The meaningless zeros are just not printed. – luator Nov 15 '16 at 10:14
  • About publishing with ROS: you said you read the tutorials. Can you narrow a bit down, which part you didn't understand? Have you tried simply copying the code from the publisher tutorial and modifying it, until it does what you want? – luator Nov 15 '16 at 10:17
  • Thanks for your reply and your clarifications @luator . Yeah, i know the zeros are meaningless, but i think (but I'm not sure) that they are necessary for the next part of my project. I tried to modify the code, i will post my efforts above. Thank you again! – Marcofon Nov 15 '16 at 10:55

2 Answers2

0

Additionally

#include <iomanip>

and then, before outputting the values

cout << setprecision(3) << heart //... etc

docos

Adrian Colomitchi
  • 3,974
  • 1
  • 14
  • 23
  • I've also noticed that the cutting appears only when the last digit is a zero, like 0.900 is cutted in 0.9 – Marcofon Nov 14 '16 at 14:53
  • @Marcofon Seems like you should also add `std::fixed` to the output http://stackoverflow.com/a/33005025/597607 – Bo Persson Nov 14 '16 at 15:01
  • Thank you!! Now it works! Any idea for the other parts? :) – Marcofon Nov 14 '16 at 15:06
  • @BoPersson I was able to put all this code on a ROS node and then run it with no problem, I'm trying to do the message part, do you have any hints? Thank you again! And thank you Adrian since one part of the solution was yours! – Marcofon Nov 15 '16 at 09:25
0

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.

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;

}
Termininja
  • 6,620
  • 12
  • 48
  • 49
Marcofon
  • 49
  • 2
  • 12