• Welcome to the Contour Enthusiasts Group, the best resource for the Ford Contour and Mercury Mystique.

    You can register to join the community.

DynoJet (WinPEP) dyno export parsing script

morbid

Hard-core CEG'er
Joined
Feb 10, 2003
Messages
1,750
Location
Phoenix, AZ
After 2 days of re-learning perl and almost missing a project deadline, I have ported over my bash script to perl. I have not tested this on windows, but it works on linux... and shouldn't have any problems on other platforms. Any feedback would be greatly appreciated! Since I had to learn perl to do this, it is mostly a direct port.. with some additional minor enhancements. I am planning on rewriting it... as I do not like that each export gets read 5 times. Still though... it parses 6 exports on my laptop in 0.145 seconds... where the bash script took ~1.250 secs.

A little background: I know the displayed peak hp/tq is cool and all, but I think average power is better to know. So I wrote a bash script (what I'm best at, so I could do it quickly). I then found that there's potentially a lot of garbage at the beginning and end of the dyno exports. So I made the script find the best "proper" starting and ending rpm. After that, I wanted it to compare multiple runs of mine... and also a local stock CSVT from the same dyno... so I made it check for the lowest and highest common "proper" rpm points.
With the recent "time" dyno from buckeyesvt, I added time trimming to the script. The findings were not surprising. The time specified by WinPEP was unreliable at best. The trimmed times are simply end_rpm_time - start_rpm_time. No correction or anything. Also unsurprising (going back to the initial purpose of the script), the quickest run times also had the highest average hp/tq -- which often conflicted with the raw WinPEP times. I really wanted to run the script against buckeyesvt's and Rickenbomb's dynos, but buckeysvt (for some reason) never even replied to my pm's.
So... here it is for your own personal consumption. I am interested in feedback... bugs and feature requests.

Please run it with "--help" first, as it explains how to properly export the dyno files, as well as certain options you can specify (like increasing the low rpm point to 5000 rpm to replicate your top end shifting).

NOTE: Specified rpm's need to match the exported rpm format: #.##
So 5000rpm would be "5.00".


NOTE(2): The "hp_min/max" and "tq_min/max" are values from the min/max rpms points... not the actual "peak" values. Also... everything to the right of the "||" are directly taken from the export (no adjusting), with the exception of the rpm's for max_hp/tq.. which the script finds.

Also... thanks to chemguru here for optimization suggestions for the original bash script!

Script:
View attachment dyno-eval.pl.zip

Sample exports. Run 001 is from the local stock CSVT; the others are mine.
View attachment sample_exports.zip

Here's an example of the script output:
Code:
$ ./dyno-eval.pl

dyno-eval.pl v1.0-20071006

RPM: low=2.470; high=7.050
File         avg_hp  hp_min/max     avg_tq  tq_min/max      TIME  max_hp@rpm    max_tq@rpm     time  temp F   baro  humid
-----------++------++-------------++------++-------------++-----||------------++------------++-----++------++-----++-----
001J [SAE]   126.89   52.83/100.93  140.33  112.32/ 75.51  15.45  165.50@6.320  153.05@4.350  17.71   86.57  28.91     5%
006 [SAE]    131.42   69.18/165.88  145.33  147.09/123.60  15.32  177.53@6.500  154.47@5.550  20.49  112.03  29.04     5%
007 [SAE]    130.35   67.19/176.40  144.02  142.88/131.43  15.43  177.09@7.040  152.46@5.550  17.73  111.98  29.01     5%
008 [SAE]    133.26   69.72/175.02  147.48  147.93/130.39  15.08  178.95@6.540  155.73@5.460  15.64  112.44  29.01     5%
009 [SAE]    133.54   69.10/175.61  147.75  146.94/130.80  15.03  178.49@6.750  155.88@5.470  17.80  111.67  29.00     5%
Here's the code:
Code:
#!/usr/bin/perl

###############################################################################
##[  Details  ]################################################################
##
## Script:      dyno-eval.pl
##
## Version:     1.0-20071006
##
## License:     Distributed under the terms of the GNU General Public License v2
##
## Purpose:     Evaluates exported dyno files
##
##              o finds average hp/tq
##              o time from actual (non-inflated) rpm entries
##              o compares files; find lowest/highest common "proper" rpm
##
## Usage:       ./dyno_eval.pl  compares all dyno files in current directory
##              -f<filename>    only parse specified file
##              -l<rpm>         raise low rpm to specified number
##              -h<rpm>         lower high rpm to specified number
##              --help          display this help
##
## Exporting a WinPEP file:
##              In the graph, ensure horizontal is set to "rpm"
##              File -> Export Data
##              All options checked in "Information / Headers"
##              "Format For Printing" should be unchecked
##              Delimiter set to "Comma"
##              For best accuracy, manually set "Step Size" to "0.01"
##              Ensure the exported filename is "DJDataExport_RunFile_###.txt"
##                      You can safely add a character after the ### to make
##                      identically named files unique (ex: ..._001S.txt)
##
###############################################################################
##[  Change History  ]#########################################################
##
## Release          xx  Details
## -------------------  ------------------------------------------------------
## 1.0-20071006     SJ  Initial release
##                      Ported from bash script (dyno-eval.sh-1.2-20071002)
##----------------------------------------------------------------------------
## SJ=Scott Jones(m0rbid@--check_zip_for_this--);
###############################################################################


#---[  variables  ]---#
$script_version = "1.0-20071006";
$script_name = $0;
$script_name =~ s#^.*/##;


#=================#
#===[  Usage  ]===#
#=================#
sub usage {
        print "\nUsage: ./$script_name {OPTION}\n";
        print "Evaluates exported Dynojet files.\n";
        print "  -f<filename>\t\tonly parse specified file.\n";
        print "  -l<rpm>\t\traise low rpm to specified number.\n";
        print "  -h<rpm>\t\tlower high rpm to specified number.\n";
        print "\n  --help\t\tdisplay this help.\n";
        print "\nNote (exporting a WinPEP file):\n";
        print "  In the graph, ensure horizontal is set to 'rpm'\n";
        print "  File -> Export Data\n";
        print "  All options checked in 'Information / Headers'\n";
        print "  'Format For Printing' should be unchecked\n";
        print "  Delimiter set to 'Comma'\n";
        print "  For best accuracy, manually set 'Step Size' to '0.01'\n";
        print "  Ensure the exported filename is 'DJDataExport_RunFile_###.txt'\n";
        print "      You can safely add a character after the ### to make\n";
        print "      identically named files unique (ex: ..._001S.txt)\n";
        print "\nReport bugs to: Scott Jones (m0rbid@--check_zip_for_this--).\n\n";
        exit 2;
}


#==============================#
#===[  Read in array data  ]===#
#==============================#
sub read_array_data {
        print "RPM: low=" . $lowest_rpm . "0; high=" . $highest_rpm . "0\n";
        $printf_format = "%-11s%8s%8s%1s%-6s%8s%8s%1s%-6s%7s%8s%1s%-5s%8s%1s%-5s%7s%8s%7s%7s\n";
        printf $printf_format, "File", "avg_hp", "hp_min", "/", "max", "avg_tq", "tq_min", "/", "max", "TIME", "max_hp", "@", "rpm", "max_tq", "@", "rpm", "time", "temp F", "baro", "humid";
        printf $printf_format, "-----------", "++------", "++------", "-", "------", "++------", "++------", "-", "------", "++-----", "||------", "-", "-----", "++------", "-", "-----", "++-----", "++------", "++-----", "++-----";
        $printf_format = "%-11s%8.2f%8.2f%1s%6.2f%8.2f%8.2f%1s%6.2f%7.2f%8.2f%1s%-5s%8.2f%1s%-5s%7.2f%8.2f%7.2f%7s\n";

        foreach $dyno_file (@dyno_file_list) {
                open(DYNO, $dyno_file);
                while (<DYNO>) {
                        if ($_ =~ m/^MAX/) {
                                @dyno_max = split(/,/);
                                last;
                        }
                }
                close(DYNO);

                open(DYNO, $dyno_file);
                while (<DYNO>) {
                        if ($_ =~ m/^,[^s-]/) {
                                @__line = split(/,/);
                                if ($__line[3] == $dyno_max[3]) {
                                        $max_hp_rpm = $__line[2];
                                }
                                if ($__line[4] == $dyno_max[4]) {
                                        $max_tq_rpm = $__line[2];
                                }
                        }
                }
                close(DYNO);

                $dyno_file_name = substr($dyno_file, 0, -4);
                $dyno_file_name =~ s#^.*_##;

                $hp_sum = 0;
                $tq_sum = 0;
                $index = 0;

                open(DYNO, $dyno_file);
                while (<DYNO>) {
                        if ($_ =~ m/Humidity/) {
                                @dyno_env = split();
                        }
                        if ($_ =~ m/^,[^s]/ && $_ !~ m/-INF/) {
                                @__line = split(/,/);
                                if ($__line[2] ge $lowest_rpm) {
                                        $hp_sum += $__line[3];
                                        $tq_sum += $__line[4];

                                        $index++;

                                        if ($__line[2] eq $lowest_rpm) {
                                                $time_start = $__line[1];
                                                $hp_l = $__line[3];
                                                $tq_l = $__line[4];
                                        }
                                }
                                if ($__line[2] ge $highest_rpm) {
                                        $time_stop = $__line[1];
                                        $hp_h = $__line[3];
                                        $tq_h = $__line[4];
                                        last;
                                }
                        }
                }
                close(DYNO);
                $time_elapsed = $time_stop - $time_start;

                $hp_avg = $hp_sum / $index;
                $tq_avg = $tq_sum / $index;

                substr($dyno_env[8], -1) = "";

                printf $printf_format, "$dyno_file_name [$dyno_env[8]]", $hp_avg, $hp_l, "/", $hp_h, $tq_avg, $tq_l, "/", $tq_h, $time_elapsed, $dyno_max[3], "@", $max_hp_rpm . "0", $dyno_max[4], "@", $max_tq_rpm . "0", $dyno_max[1], $dyno_env[1], $dyno_env[3], $dyno_env[6] . "%";
        }
}


#==================================#
#===[  Find lowest common rpm  ]===#
#==================================#
sub find_low_rpm {
        foreach $dyno_file (@dyno_file_list) {
                open(DYNO, $dyno_file);
                while (<DYNO>) {
                        if ($_ =~ m/^,[^s]/ && $_ !~ m/-INF/) {
                                @__line = split(/,/);
                                if ($__line[4] > 99.99) {
                                        $low_rpm = $__line[2];
                                        if ($low_rpm >= $lowest_rpm) {
                                                $lowest_rpm = $low_rpm;
                                        }
                                        last;
                                }
                        }
                }
                close(DYNO);
        }
}


#===================================#
#===[  Find highest common rpm  ]===#
#===================================#
sub find_high_rpm {
        foreach $dyno_file (@dyno_file_list) {
                $high_rpm = 0;

                open(DYNO, $dyno_file);
                while (<DYNO>) {
                        if ($_ =~ m/^,[^s]/ && $_ !~ m/-INF/) {
                                @__line = split(/,/);
                                if (defined($highest_rpm)) {
                                        if ($__line[2] > $highest_rpm) {
                                                last;
                                        }
                                }
                                if ($__last_hp - $__line[3] > 20.00 && $__line[2] > 6.00) {
                                        last;
                                }
                                $__last_hp = $__line[3];
                                $high_rpm = $__line[2];
                        }
                }
                close(DYNO);

                if ($high_rpm <= $highest_rpm || $high_rpm) {
                        $highest_rpm = $high_rpm;
                }
        }
}




#---[  main  ]-----------------------------------------------------------------

print "\n$script_name v$script_version\n\n";

while (defined($_ = shift)) {
        /^-l/           && do { $lowest_rpm = substr($_, 2);
                                if ($lowest_rpm eq "") {
                                        print "Lowest RPM value not specified.\n";
                                        exit 1;
                                } next };
        /^-h/           && do { $highest_rpm = substr($_, 2);
                                if ($highest_rpm eq "") {
                                        print "Highest RPM value not specified.\n";
                                        exit 1;
                                } next };
        /^-f/           && do { $dyno_file_list[0] = substr($_, 2);
                                if ($dyno_file_list[0] eq "") {
                                        print "Dyno file not specified.\n";
                                        exit 1;
                                } elsif (! -e $dyno_file_list[0]) {
                                        print "Specified dyno file not found: $dyno_file_list[0]\n";
                                        exit 1;
                                } next };
        /^--help/       && do { usage(); };
}
if (!defined($dyno_file_list[0])) {
        @dyno_file_list = <DJ*>;
}

find_low_rpm();
find_high_rpm();
read_array_data();
 
Last edited:
Wow nice!

So this only works in unix? Is there any way to convert this to be used in Windows?

I can send you he winpep files of a few of my dyno's from the past if you like. Not all dyno operators were very good at including the files though.
 
Wow nice!

So this only works in unix? Is there any way to convert this to be used in Windows?

I can send you he winpep files of a few of my dyno's from the past if you like. Not all dyno operators were very good at including the files though.

Thanks! My initial bash script only worked with unix. The purpose of me rewriting it in perl is so that it's cross-platform -- will work on anything can that run perl.

Perl for windows: http://www.activestate.com/Products/activeperl/

Although... if you don't mind sending me some .drf's, I would like to be able to test it against more files. I've currently only tested it against 11 of mine, 3 from a local stock CSVT, and 3 from my brothers Mirage.

There are some parts that I'm not 100% satisfied with, but it works. For example... the low rpm is determined by the first rpm with torque above 99.99. And the high rpm is determined when the next rpm has horsepower that's 20 or more lower than the current hp. From manually viewing the exported files, this seems to work... at least for our platform. My goal was to try to figure out when the car is WOT and when the throttle is released. Though... this also seemed to work for my brothers Mirage, which has significantly less hp & tq.

If anyone has any suggestions, please let me know. I thought about adding in support for gear ratios, so it'll roughly estimate quarter mile runs... but I think that would require alot of time, which is something I don't have much of right now.
 
Here's version 2.0. I rewrote most of it to use arrays instead of constantly hitting the files. Now runs in less than 1/2 the time -- 0.068 seconds for 6 exports. :)
 

Attachments

  • dyno-eval.pl-2.0.zip
    2.3 KB · Views: 0
cool! It *could* be even better if WinPEP allowed command line exporting, instead of having to get into the gui to do it. Hmm... I'll email them requesting that feature.

Also... if you think anything is missing, please let me know. The exported files contain lots of data and I keep thinking that more can be done with it.
 
So I got a quick reply from Dynojet. I asked if WinPEP could support a command line option for exporting, and/or a stand alone app to export.

I will support these 11 (two) requests to our Software Engineering staff.
Honestly the requests that you are asking for, while valid, are way outside of the realm of knowledge of our basic dynamometer user.
We'll see what we can do.
Dunno what the "11" was for. I think it may have been an attempt at binary as my email signature has: "There are 10 types of people in the world; those who understand binary, and those who don't."

If they do supply a method to automate exporting, then you could just upload the drf's and have the site take care of the rest. Eliminating the possibility of human error during the export options or file naming.
 
anyone good with physics?

anyone good with physics?

Ok. I have the gearing and calculated mph done (for shift points, etc...), but I'm having difficulties with the physics. I'm not sure which formula I need to determine how much time it will take to accelerate. I'm also not sure if it's torque (force) or horsepower (power) that's needed... I may even be incorrect on the force/power correlations.

I believe that F=ma might be the correct formula, but if force is torque, and mass is the cars weight... is acceleration mph? If not, should I solve for acceleration by a=F/m ? If so, I haven't been able to determine the measurement of "a". Seconds, ms.... or am I completely wrong here?
 
Acceleration is in units of distance over time squared, so meters per second squared, feet per second squared, miles per hour squared, etc., with the first two being most common.

I'm not sure exactly what you're trying to do here...are you trying to find the instantaneous acceleration at one certain data point, or are you looking for the average acceleration over a certain amount of time?
 
I think I'm was wanting to find out how much time it takes to accelerate from a certain rpm (like 5000) to a certain rpm (like 7000), based off the dyno'd tq/hp readings. So I was figuring that every dyno point (100rpm) acceleration (or velocity) would need to be calculated, then those would be totaled to figure the total run time.

So if acceleration can basically be mph (squared)... and I have the hp/tq & rpm for every 100rpm's, and with rpm and gearing info I can calculate what the mph is, I'm not exactly sure what I'm after.

I hope all that makes sense. I have a feeling that I don't know enough about this to properly explain what I'm after.
 
Actually... that was one of the sites I was looking at. I could only find partial formulas there... the closest I found was calculating quartermile time based off an estimated constant g, not dynamic based off tq or hp. Lots of good info there though.
 
Ok here is an idea.

Power = force * velocity
p=fd

force = mass * acceleration
f=ma

therefore

p=(ma)v

ma=p/v
a=p/mv

acceleration is power divided by the product of mass and velocity

so some pseudo might be:

hp = getHP(rpms);
velocity = getVelocity(rpms);

convert horsepower to Newton*meters/sec :

1 hp = 746 Nm/s

power = hp*746;

accel = power/(mass * velocity); that will give you instantaneous acceleration

velocity is the rotational velocity of the wheels at the given rpm in m/s
1 mi/hr = 0.447m/s

not sure where your mass is going to come from, but I would think the wheels?? <- just a guess on my part :
1lb = 453.592g

now i might be totally wrong with all of that but its a shot!:laugh:


 
Okay, I did some things.
I attached an Excel sheet of one data set with the instantaneous acceleration calculated using the formula:
a=p/mv
where:
a=instantaneous acceleration
p=horsepower*746 (this puts power in Nm/s)
m=3000lbs=1360kg
v=rpm*(0.447/58.92) (where 0.447 converts mph to m/s and 58.92 is the gear ratio for 4th gear. For the other gears, I found the gear ratios on another site and converted them to a compatible number)

This should result in instantaneous acceleration in unit of meters per (second) squared. My answers seem to be off by a factor of ten, as I doubt a 150hp car can pull 6gs, but 0.6gs is perfectly acceptable, according to this wonderful site.
 

Attachments

  • instantaneous acceleration v2.xls.zip
    53.1 KB · Views: 0
Last edited:
Back
Top