Reading float type from a file and using them in formulas

Pages: 12
Yes and here are the printed instructions stating that I have to derive acceleration and velocity data from the input file. My problem is that I now have a code that at least outputs something but it repeats the same numbers the entire time and they aren't correct. It isn't even outputting the same numbers from the input file.

The moving trajectory of a robotic arm was recorded by an attached optical sensor and saved in the following text file: M3 Array File (TXT). Velocity and acceleration sensors are both not available. However, velocity and acceleration data are required for the controller used to compensate the robotic arm. Write a program that can derive and store the information of time, position, velocity, and acceleration on disk.
@Vaughnpkk,

Are you sure that your input file as given earlier is the original, or have you re-exported it from Excel or something, reducing the number of decimal places.

If the columns given are
t x
(and I suspect they are), then the small relative increments from point to point make it difficult to get an accurate velocity and well-nigh impossible to get an accurate acceleration.


In your last post you are also going outside array bounds.
Last edited on
Maybe this throws some light on perhaps what everybody here already knows.
1) The code by OP is littered with C-style 'obscurity', well meaning but aggravatingly 'obfuscatory' - but never 'fatuous'.
2) Assuming my calculus sums are right there does appear to be 'meaningful' numbers coming out - the machine stops/starts etc - even decelerates and comes to a halt at the end.
3) Initial conditions might be a problem but intuitively the numerous starting zeroes are good enough for me.
4) The only way to check validity is to see the 'markers' results/expectation.
5) Maybe the intent is to (easy to do) filter out the times when the machine is stationary (V == A == 0)?

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
#include <iostream>
#include <fstream>
#include <iomanip>

const int COUNT{3000};

int main ()
{
    std::ifstream myfile ("velocity_acc.txt");
    
    double t[COUNT]{0};  // ELAPSED TIME
    double x[COUNT]{0};  // TOTAL DISTANCE TRAVELLED
    double dt[COUNT]{0}; // TIME INCREMENT
    double ds[COUNT]{0}; // DISTANCE INCREMENT
    double V[COUNT]{0};  // INSTANTANEOUS VELOCITY
    double dV[COUNT]{0}; // VELOCITY INCREMENT
    double A[COUNT]{0};  // ACCELERATION
    
    if (myfile.is_open())
    {
        int counter{0};
        while ( myfile >> t[counter] >> x[counter])
        {
            counter++;
        }
        myfile.close();
        
        for(int i = 1; i < COUNT; i++)
        {
            dt[i] = t[i] - t[i-1];
            ds[i] = x[i] - x[i-1];
            V[i] = ds[i]/dt[i];
            dV[i] = V[i] - V[i - 1];
            A[i] = dV[i]/dt[i];
            
            std::cout
            << std::setw(10) << std::right << t[i]
            << std::setw(10) << std::right << dt[i]
            << std::setw(10) << std::right << ds[i]
            << std::setw(10) << std::right << V[i]
            << std::setw(10) << std::right << dV[i]
            << std::setw(10) << std::right << A[i]
            << '\n';
        }
    }
    else
        std::cout << "Unable to open file";
    
    return 0;
}


OOPs, forgot. My text file is the downloaded one unchanged, just renamed for my purposes
Last edited on
The code by OP is littered with C-style 'obscurity',

It's not C-style ... it's C! That's apparently the language he's using, so he may not be able to change to C++. But that's his problem.

BTW, you don't need the arrays as shown below.

Looks like you're on to something, but I don't know if it's actually correct. This bit doesn't look right. It seems too simplistic.

     t          x          v          a
     0.029      0.000      0.000      0.000
     0.030      0.002      2.000   2000.000
     0.031      0.003      1.000  -1000.000
     0.032      0.005      2.000   1000.000
     0.033      0.005      0.000  -2000.000
     0.034      0.005      0.000      0.000
     0.035      0.005      0.000      0.000


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
#include <fstream>
#include <iostream>
#include <iomanip>

int main()
{
    std::ifstream fin ("M3 Array File.txt");
    if (!fin)
    {
        std::cerr << "Unable to open the input file.\n";
        return 1;
    }

    std::cout << std::setprecision(3) << std::fixed;

    double t0 = 0, x0 = 0, v0 = 0;
    fin >> t0 >> x0;

    for (double t, x; fin >> t >> x; )
    {
        using std::setw;

        double dt = t  - t0;
        double dx = x  - x0;
        double v  = dx / dt;
        double dv = v  - v0;
        double a  = dv / dt;

        std::cout << setw(10) << t << ' '
                  << setw(10) << x << ' '
                  << setw(10) << v << ' '
                  << setw(10) << a << '\n';

        t0 = t;
        x0 = x;
        v0 = v;
    }
}

Last edited on
C'mon dutch C or C-style is a gnat's bum of semantic difference with or without a '!'.

True, know/knew we don't need arrays/containers - my program, my control, my call.

Plotting V gives a fairly nice inverted V/U shape curve, A is jerky which makes it clearer from what the numbers show. Filtering doesn't do anything beyond getting rid of very small changes AFAICS

The next post process is to measure jerk ( = dA/dt believe it or not ) and with that we are back at square one :)

Maybe there is some secret recipe in robotics that the simple calculus of motion renders OP's equations correct. Mechanical engineers are sometimes as as rough as guts :)
I'm compiling this program using C++ just as a heads up. @dutch in response to your question earlier the text file is as exactly as I received it. I have somewhat updated my code but my problem is that the results need to be put out into a different text file. My current iteration of code is as follows.

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
#include <stdlib.h>
#include <stdio.h>


int main()
{
    static float time[3000];
    static float posit[3000];
    static float vel[3000];
    static float acc[3000];

    float i;
    float dt;
    int x;

    FILE *fp;

    fp=fopen("M3 Array File.txt", "r+");
    for(x=2;x<=3000;x++)
    {
        fscanf(fp,"%f",&dt);
        time[x]=dt;
        fscanf(fp,"%f",&i);
        posit[x]=i;
    }
    fclose(fp);
    for(x=2;x<=3000;x++)
    {
        vel[x]=(posit[x]-posit[x-1])/(time[x]-time[x-1]);

    }
     for(x=2;x<=3000;x++)
{
        acc[x]=(2*(posit[x]-posit[x-1]-vel[x-1]));

     }
        fp=fopen("results.txt","w");
        for (int y=1;y<=3000;y++)
            {
    fprintf(fp,"%.3f\t%.3f\t%.3f\t%.3f\n", time[x],posit[x],vel[x],acc[x]);
        }
        fclose(fp);
    return 0;
}


By the way, you guys are awesome for taking the time to help me out! I really appreciate it!
Last edited on
@OP et al
Here's my latest version which should be self-evident.

On the 'issue' of C vs C++ it's really the code commands. C++ might look a bit weird to someone versed in C but the difference is worth chasing unless you are faced with legacy code etc.

And on J for jerk, evaluating that doesn't tell me much :(

I learned a bit out of it too. I've been using XCode for a long time and used its automatic facility to extract a group of code and extract it as a function. Other IDE's have it no doubt, but it's not to bad at all.

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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cmath>

const int COUNT{3000};

void display_results
 (
  double *A, double *V, int col_width, double *J,
  double *dA, double *dV, double *ds, double *dt, int i, double *t )
{
    std::cout
    << std::fixed << std::setprecision(3)
    << std::setw(col_width) << std::right << t[i]
    << std::setw(col_width) << std::right << dt[i]
    << std::setw(col_width) << std::right << ds[i]
    
    << std::fixed << std::setprecision(1)
    << std::setw(col_width) << std::right << V[i]
    << std::setw(col_width) << std::right << dV[i]
    
    << std::fixed << std::setprecision(0)
    << std::setw(col_width) << std::right << A[i]
    << std::setw(col_width) << std::right << dA[i]
    
    << std::setw(col_width) << std::right << J[i]
    
    << '\n';
}

void display_results_spaced
 (double *A, double *V, int col_width, double *J,
  double *dA, double *dV, double *ds, double *dt, int i, double *t )
{
    std::cout
    << t[i] << ' '
    << dt[i] << ' '
    << ds[i] << ' '
    << V[i] << ' '
    << dV[i] << ' '
    << A[i] << ' '
    << dA[i] << ' '
    << J[i]
    
    << '\n';
}

int main ()
{
    std::ifstream the_read_from_file ("velocity_acc_read_from.txt");
    
    double t[COUNT]{0};  // ELAPSED TIME
    double x[COUNT]{0};  // TOTAL DISTANCE TRAVELLED
    double dt[COUNT]{0}; // TIME INCREMENT
    double ds[COUNT]{0}; // DISTANCE INCREMENT
    double V[COUNT]{0};  // INSTANTANEOUS VELOCITY
    double dV[COUNT]{0}; // VELOCITY INCREMENT
    double A[COUNT]{0};  // ACCELERATION
    double dA[COUNT]{0}; // ACCELERATION INCREMENT
    double J[COUNT]{0};  // JERK = dA/dt
    
    if (the_read_from_file.is_open())
    {
        int counter{0};
        while ( the_read_from_file >> t[counter] >> x[counter])
            counter++;
        
        the_read_from_file.close();
    }
    else
    {
        std::cout << "Unable to open file\n";
        return -1;
    }
    
    int col_width{9};
    
    std::string label[] = {"t", "dt", "ds","V","dV", "A","dA","J"};
    int size = sizeof(label)/sizeof(std::string);
    
    for(int i = 0; i < size; i++)
    {
        std::cout
        << std::setw(col_width) << std::right << label[i];
    }
    std::cout
    << '\n'
    << std::string(size * col_width, '-')
    << '\n';
    
    
    for(int i = 1; i < COUNT; i++)
    {
        dt[i] = t[i] - t[i-1];
        ds[i] = x[i] - x[i-1];
        V[i] = ds[i]/dt[i];
        dV[i] = V[i] - V[i - 1];
        A[i] = dV[i]/dt[i];
        dA[i] = A[i] - A[i - 1];
        J[i] = dA[i]/dt[i];
        
        bool filter_on{true};
        
        if(filter_on == false)
        {
            if(std::abs( A[i]) > .0000001 && std::abs(V[i]) > 0.0000001)
                display_results
                ( A, V, col_width, J, dA, dV, ds, dt, i, t );
        }
        else
            display_results
            ( A, V, col_width, J, dA, dV, ds, dt, i, t);
        
        // OUTPUT TO FILE USING DREADED C (style even)
        FILE *fptr;
        fptr = fopen("velocity_acc_write_to.txt","w");
        if(fptr == NULL)
        {
            printf("Error!");
            exit(1);
        }
        else
        {
            for(int i = 0; i < COUNT; i++)
            {
                fprintf(fptr,"%f %f %f %f\n", t[i], V[i], A[i], J[i]);
            }
        }
        fclose(fptr);
    }
    
    return 0;
}


EDIT: Added output to file. Note all this could have been done with overloaded >> and << operators ...
Last edited on
Well, here's how I would like to have done it (centred differences for first and second derivatives of x(t)):
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
#include <iostream>
#include <fstream>
#include <iomanip>
#include <vector>
using namespace std;

#define FMT << setw( 12 ) << fixed << setprecision( 3 ) << ' ' <<

struct Pt{ double t, x, v, a; };

ostream &operator << ( ostream &out, Pt p ) { return out FMT p.t FMT p.x FMT p.v FMT p.a; }

int main()
{
   vector<Pt> P;

   // Read points
   ifstream in( "in.txt" );
   for ( double t, x;  in >> t >> x; ) P.push_back( { t, x, 0.0, 0.0 } );

   // Compute velocities
   for ( int k = 1; k < P.size() - 1; k++ ) P[k].v =  ( P[k+1].x - P[k-1].x ) / ( P[k+1].t - P[k-1].t );

   // Compute accelerations
   for ( int k = 1; k < P.size() - 1; k++ ) P[k].a =  ( P[k+1].x - 2 * P[k].x + P[k-1].x ) / ( P[k+1].t - P[k].t ) / ( P[k].t - P[k-1].t );

   // Output
   ofstream out( "out.txt" );
   for ( auto p : P ) out << p << '\n';
}



If you use the OP's equations instead then the results are worse:
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
#include <iostream>
#include <fstream>
#include <iomanip>
#include <vector>
using namespace std;

#define FMT << setw( 12 ) << fixed << setprecision( 3 ) << ' ' <<

struct Pt{ double t, x, v, a; };

ostream &operator << ( ostream &out, Pt p ) { return out FMT p.t FMT p.x FMT p.v FMT p.a; }

int main()
{
   vector<Pt> P;

   // Read points
   ifstream in( "in.txt" );
   for ( double t, x;  in >> t >> x; ) P.push_back( { t, x, 0.0, 0.0 } );

   // Compute velocities
   for ( int k = 1; k < P.size(); k++ ) P[k  ].v = 2 * ( P[k].x - P[k-1].x ) / ( P[k].t - P[k-1].t ) - P[k-1].v;

   // Compute accelerations
   for ( int k = 1; k < P.size(); k++ ) P[k-1].a =     ( P[k].v - P[k-1].v ) / ( P[k].t - P[k-1].t );

   // Output
   ofstream out( "out.txt" );
   for ( auto p : P ) out << p << '\n';
}



The problem is that the input data is too low-res.

I get similar results to @Dutch (at least with the first code). The velocity is just about tolerable; the acceleration is meaningless because the data it is calculated from has too few sig figs.
Well, here's how I would like to have done it (centred differences for first and second derivatives of x(t)):
It's no surprise that would rear it's head but the whole problem is you can't make a silk purse ...

Why not apply some sort of concoction of weighted rolling averages at the third points ... over ten readings, maybe 20, why not a 1000.

Gloomy isn't it when things have to be force-fitted and won't because there just isn't enough information, even the manufactured type. :(

Integrating the result would be interesting though to have some sort of handle on the error margin. My guess is if you were designing a robot it wouldn't count for a twopenny in the final outcome.
C'mon @lastchance

It's all in good faith to help OP. OP is stuck with minimally accurate data so we can't tell him/her it's a no answer - all that does is get no marks at all. You know that being an academic.

So the answer has limits. It always does. Nothing's (perfectly) real - cf https://www.edge.org/conversation/donald_d_hoffman-realism-is-false, the latest in a long line of scientific reality - sufficiency vs absolutism - heavy.

Now, don't be afraid, it's in good faith, what does integration of the 4(?) approaches give us? Sort of reverse Runge-Kutta integration of the results stuff.

As a start, I'm surprised the V plot is so apparently regular/continuous while the A plot is so irregular.



Last edited on
As a start, I'm surprised the V plot is so apparently regular/continuous while the A plot is so irregular.

Mmm, me also. And it seems a little unfair on the OP, although it could be introducing him/her to the real world of sensor measurements.


If you take every 20th point (say) then the changes in x are sufficiently large compared with the relative error induced by rounding to produce a very smooth velocity and tolerably smooth acceleration.

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
#include <iostream>
#include <fstream>
#include <iomanip>
#include <vector>
using namespace std;

#define FMT << setw( 12 ) << fixed << setprecision( 3 ) << ' ' <<

struct Pt{ double t, x, v, a; };

ostream &operator << ( ostream &out, Pt p ) { return out FMT p.t FMT p.x FMT p.v FMT p.a; }

int main()
{
   vector<Pt> P;

   // Read points
   ifstream in( "in.txt" );
   int counter = 0, frequency = 20;
   for ( double t, x;  in >> t >> x; counter++ ) if ( counter % frequency == 0 ) P.push_back( { t, x, 0.0, 0.0 } );

   // Compute velocities
   for ( int k = 1; k < P.size() - 1; k++ ) P[k].v =  ( P[k+1].x - P[k-1].x ) / ( P[k+1].t - P[k-1].t );

   // Compute accelerations
   for ( int k = 1; k < P.size() - 1; k++ ) P[k].a =  ( P[k+1].x - 2 * P[k].x + P[k-1].x ) / ( P[k+1].t - P[k].t ) / ( P[k].t - P[k-1].t );

   // Output
   ofstream out( "out.txt" );
   for ( auto p : P ) out << p << '\n';
}
Last edited on
To be clear from my POV we have been more than fair to the OP. I doubt a university tutor would give a student the attention and help we have given in a combined effort. Any unfairness would be to dismiss the problem as too uncertain numerically, and that hasn't happened :)

A longer time span would certainly make difference to At, but keep in mind the existing V(t) curve is fairly smooth as I wrote earlier. I plotted it, maybe you have. I'll plot the lot because at the moment I don't know whether there's much difference.

Obviously you aren't obliged to but integrating the results will probably put bounds on the errors involved.

Perhaps it's simply the A(t) values are similar to what happens in reality and the apparent lack of refinement is near/good enough. Any uncertainty is taken up in mechanical engineering safety factors and large HD bolt/baseplate/foundation assemblies in factories. (I might be out of date but LS design is not a mech eng thing, or wasn't until recently if there has been a change).
PS On reflection, the only 'unfairness' is OP knowing the answers while we don't.

Just joking ... I don't want to know, certainly for a month or two at the earliest, if at all.
I'll be honest with everyone. The professor tried to help me out but every time I go back for a question he doesn't really give me an answer other than "I'm in the fine-tuning stage" of my work by which I mean given my rewritten code I could even get the input data to output on a new file and the professor certainly didn't help with that. I greatly appreciate everything that everyone has given me and this has helped me tremendously. I will let you all know how it turns out and hopefully with good results.
@dutch
It seems too simplistic.
No 'umbrage' was taken but FWIW I take my lead in classical mechanics from Isaac Newton, Galileo, Leibniz and in later times from Prof Leonard Susskind and Euler. E&O on my part, their simplicity and clarity beats anything I can do.

@Vaughnpkk :)
Last edited on
You guys rock!! Perfect score!!
Topic archived. No new replies allowed.
Pages: 12