6.5 Grendel Forum
Garmin Xero C1 Pro chrono - Printable Version

+- 6.5 Grendel Forum (https://65grendel.com)
+-- Forum: 6.5 GRENDEL DISCUSSION FORUMS (https://65grendel.com/forumdisplay.php?fid=3)
+--- Forum: 6.5 Grendel Ammunition & Reloading (https://65grendel.com/forumdisplay.php?fid=10)
+--- Thread: Garmin Xero C1 Pro chrono (/showthread.php?tid=26009)

Pages: 1 2 3 4 5 6


Garmin Xero C1 Pro chrono - SDW - 01-16-2024

I'm curious what the future Xero C1 Pro, version 2 (C2?) will be like. But I didn't see a point in waiting that long. Too many loads of various cartridges/calibers to test ASAP. Before I do any more handloading I'll need to know which loads to load. I'm tired of my Caldwell's bulky and unreliable nature. And I have a Magnetospeed Sport, but it's not suitable for some of my guns. Specifically, levergun, Lee-Enfield, several handguns....

I wouldn't mind seeing the release notes on 3.20 either. See what bugs it might have fixed and what bugs it might have had to leave in for now.


Garmin Xero C1 Pro chrono - Zeneffect - 01-16-2024

found this. fit to csv converter... makes pulling the sessions to the PC a bit easier as you convert usable files.

https://github.com/bmghunter/FitToCsv

https://github.com/bmghunter/FitToCsv/releases/tag/0.0.0.1


Garmin Xero C1 Pro chrono - mtnlvr - 01-16-2024

I created a folder on my computer to share via Google Drive. It's pretty quick to share to Drive from Shotview (except you may want to force a unique filename). Then it's instantly accessed on any PC with Drive access.

I would like to see some updates that allow the use of rifle profiles with pre setup cartridges and better file exporting (like including more in the CSV and perhaps auto incrementing session ID).


Garmin Xero C1 Pro chrono - Zeneffect - 01-16-2024

Played with that app... it sucks. Went digging

https://developer.garmin.com/fit/fitcsvtool/

*edit*

Playing around with it, and it would *appear* to just shit out random garbage for the velocity, however its not garbage. Looking through the code of the other converter I see an extra step taking the values from column H and dividing by 304.8 which gives the actual velocity number.

Trying to dig through docs to see why its represented this way but thats the math.


Garmin Xero C1 Pro chrono - grayfox - 01-16-2024

Did a little searching. the conversion factor 304.8 is feet to millimeters.
Feet to Millimeters calculation
Millimeters = Feet * 304.79999025
Millimeters = 1 * 304.79999025

Feet to Millimeters conversion: ft to mm calculator (metric-conversions.org)


Garmin Xero C1 Pro chrono - Zeneffect - 01-16-2024

Awesome, so we know the default unit and we can use this to convert whatever we want.

Excellent work, I see a quick and dirty script or excel sheet on the horizon. The way the garmin sdk works is you can drag and drop the fit files onto the converter bat file in the Java directory of the sdk. A script one could just drag and drop to then do the conversions and output a nicer csv would be ideal.



Prompt user for measurement (fps, m/s, mph, kmph, maps whatever)
Get and display list of fit files, in chronological order (so it matches session number)

Prompt user with session option to rename
Convert fit to csv
Convert/copy csv to cleaned/refactored up csv + rename


Cleaned up csv data should include shot velocity list in desired unit in order of first to last shot taken, time and date, session name (from file name), sd, es, average

Anything missing? Looking at the requirements this is pretty trivial to make.

*edit

The timestamp field is UTC timestamp format. fun... looking at powershell to do this all... (([System.DateTimeOffset]::FromUnixTimeSeconds($unixTime)).DateTime.ToLocalTime()).ToString("s")


Garmin Xero C1 Pro chrono - Zeneffect - 01-16-2024

and im now setting up the rigging to get this working. This is the cleanup of the CSV part that im working on since FIT to CSV is already provided. This is written in windows powershell by me, just now with some ripping off of the select-file function and time conversion. It will read the garmin converted CSV and output it into normal looking stuff on the screen in the command window. I'll have it output to a file, im just getting through proof of concept now.

My intended workflow is this... Plug garmin directly into PC. Take the .FIT files and drag + drop them onto a shortcut, out comes nicely formatted text file with all the information i need. this isnt quite there yet... but its pretty dang close.

*edit*

made it output to file (that you name) and you can batch select multiple files at once. Now onto getting the fit to csv workflow going to have this a 1 step operation.

Code:
cls Add-Type -AssemblyName System.Windows.Forms function Select-File { [CmdletBinding()] param( [Parameter(ParameterSetName="Single")] [Parameter(ParameterSetName="Multi")] [Parameter(ParameterSetName="Save")] [string]$StartingFolder = [environment]::getfolderpath("mydocuments"), [Parameter(ParameterSetName="Single")] [Parameter(ParameterSetName="Multi")] [Parameter(ParameterSetName="Save")] [string]$NameFilter = "All Files (*.*)|*.*", [Parameter(ParameterSetName="Single")] [Parameter(ParameterSetName="Multi")] [Parameter(ParameterSetName="Save")] [switch]$AllowAnyExtension, [Parameter(Mandatory=$true,ParameterSetName="Save")] [switch]$Save, [Parameter(Mandatory=$true,ParameterSetName="Multi")] [Alias("Multi")] [switch]$AllowMulti ) if ($Save) { $Dialog = New-Object -TypeName System.Windows.Forms.SaveFileDialog } else { $Dialog = New-Object -TypeName System.Windows.Forms.OpenFileDialog if ($AllowMulti) { $Dialog.Multiselect = $true } } if ($AllowAnyExtension) { $NameFilter = $NameFilter + "|All Files (*.*)|*.*" } $Dialog.Filter = $NameFilter $Dialog.InitialDirectory = $StartingFolder [void]($Dialog.ShowDialog()) $Dialog.FileNames } $fit = (Select-File -StartingFolder "C:\" -NameFilter "Garmin FIT Files (*.fit)|*.fit" -AllowMulti) copy $fit .\fit_Temp $fit_temp = get-childitem -Path .\fit_temp | select-object fullname foreach ($fitfile in $fit_temp) { $fit3 = $fitfile.fullname $fit2 = "`"$fit3`"" start-process -filepath '.\java\fittocsv.bat' -argumentlist $fit2 -wait } move-item -path .\fit_temp\*.csv -destination .\results\ $csv1 = import-csv (get-childitem -Path .\Results\*.csv) $customarray = @() foreach ($csv in $csv1) { $time = (([System.DateTimeOffset]::FromUnixTimeSeconds($time_hack)).DateTime.ToLocalTime()).ToString("s") $type = $csv.type $localnumber = $csv."local number" if ($type -eq "Data" -and $localnumber -eq "3") { $min = ($csv."Value 2" / 304.79999025) $max = ($csv."Value 3" / 304.79999025) $average = ($csv."Value 4" / 304.79999025) $shots = $csv."Value 6" $time_hack=$csv."Value 1" $extreme_spread= ($max - $min) Write-host "Session Time/Date:", $time Write-host "# of Shots:", $shots Write-host " " Write-host "Min:", $min Write-host "Max:", $max Write-host "Average:", $average Write-host "Extreme Spread:", $extreme_spread write-host " " write-host " " write-host " " $Session_name = Read-Host -Prompt "Enter Session Name" Write-output "Session Time: $time" | out-file -filepath .\Results\$Session_name.txt -Append Write-output "# of Shots: $shots" | out-file -filepath .\Results\$Session_name.txt -Append Write-output "Min: $min" | out-file -filepath .\Results\$Session_name.txt -Append Write-output "Max: $max" | out-file -filepath .\Results\$Session_name.txt -Append Write-output "Average: $average" | out-file -filepath .\Results\$Session_name.txt -Append Write-output "Extreme Spread: $extreme_spread" | out-file -filepath .\Results\$Session_name.txt -Append Write-output " " | out-file -filepath .\Results\$Session_name.txt -Append } # $customarray = @() # $line = "" | select min,max,average,sessiontime,time,velocity,shotnum # $line.min = $min # $line.max = $max # $line.average = $average # $line.sessiontime = $time # $line.shotnum = $shot_num # $line.time = $time1 # $line.velocity = ($speed / 304.79999025) if ($type -eq "Data" -and $localnumber -eq "4") { $shot_num = $csv.'Value 3' $speed = ($csv.'Value 2' / 304.79999025) $time_hack1=$csv."value 1" $time1 = (([System.DateTimeOffset]::FromUnixTimeSeconds($time_hack1)).DateTime.ToLocalTime()).ToString("s") Write-output " " | out-file -filepath .\Results\$Session_name.txt -Append Write-output "Shot #: $shot_num" | out-file -filepath .\Results\$Session_name.txt -Append Write-output "Speed: $speed" | out-file -filepath .\Results\$Session_name.txt -Append Write-output "Time of Shot: $time1" | out-file -filepath .\Results\$Session_name.txt -Append Write-output " " | out-file -filepath .\Results\$Session_name.txt -Append } }


*EDIT*

This should be pretty complete now. Can batch select many sessions and convert them all to readable txt as well as CSV (keeps both copies in "results" folder)


Garmin Xero C1 Pro chrono - grayfox - 01-17-2024

Your programming stuff is 'wayyy beyond me!!! lol.

Me, I'd just copy/save the csv, then cut/paste in say 2 columns for the conversion factor and result...
I'd find a way to do it all in xls. Some apps give you trouble when there are extensions, macros, etc. If this doesn't involve that then can ignore that comment.

Not a programmer at heart. For those that are, more power to ya!


Garmin Xero C1 Pro chrono - Zeneffect - 01-17-2024

well i updated the powershell script. Requires the Garmin SDK and java. Place the script in the root directory (1 up from the "java" directory in the sdk")

scripts FIT to TXT output in FPS, and adjusts time to your time zone in the text file.

The way its setup is it should copy over everything to some temporary directories so that we might be able to do the conversion while the device is connected and we dont need to pre-copy anything (just tested it direct from the device)

text output looks like this.. need to fix a time bug it seems:

Min
108.195541518722
Max
108.195541518722
Average
108.195541518722
# of Shots
1
Time
2004-01-13T17:18:43


Shot #
1
Speed
108.195541518722
Time of Shot
2004-01-13T17:20:01


Garmin Xero C1 Pro chrono - grayfox - 01-17-2024

Possibly some kind of julian date, from a base date-point. 20 years too far back (ie, 2024)?
And.... umm, 108 ft/sec?


Garmin Xero C1 Pro chrono - Zeneffect - 01-17-2024

that was a nerf gun. 108fps is correct.

https://drive.google.com/drive/folders/1fb_MCyteiMZrcL-gj7DJXlCn-Y_LsGkO?usp=drive_link

anyways, stripped the sdk down to bare bones so my google drive folder should have everything needed minus instructions. you need to have java to run. i will fix it up a little later, but needs to run in ISE, and the path needs to be the same as where the script lives in the terminal.

*edit* and I think i fixed the way it should run.

download folder, extract all somewhere - right click the Garmin_CSV_Converter_To_USA.ps1 file - run in powershell (you might need to open the file, add a # or something at the end then save to get around execution level warning/error because I wrote this today so its not signed) When prompted with a file explorer prompt, point to the FIT files either on the device or anywhere else if you offload them (it will copy to the fit_temp folder as a backup anyways and work from there rather than on the device)

There will be a summary displayed on the screen with a prompt for "Session Name" - Now is the time to name the session. The session name will be the name of the text file, spaces are ok.

The TXT file results appear in the "Results" folder as does the unmodified CSV file and can be opened with anything, its a text file.


So why bother doing this? If you notice, you can select multiple files at once and it processes them in a batch. It will display a summary and prompt to name for each one. I dont think Garmin or whatever that other software is allows for this functionality and I kinda of really need it if I am doing a OCW test.

I'll add ES and SD as well, but not right now. it was a headache enough to get the user interaction as minimal as possible. The bones are built, now can add features and fix minor bugs


Garmin Xero C1 Pro chrono - lazyengineer - 01-17-2024

Have you figured out how to extract the trace data for each shot?


Garmin Xero C1 Pro chrono - Zeneffect - 01-17-2024

If you mean down-range no, I don't see that data.

If you mean each shots muzzle velocity then yes.


Garmin Xero C1 Pro chrono - Zeneffect - 01-17-2024

Powershell 7 makes standard deviation a function of measure-object

For compatibility, I need to do this with powershell 5 which I need to make that function it seems...

Es is easy and done.

*edit*

making SD function is weird. i might need to run the math manually to double check but im not getting exactly as expected, suspect coding error or math error somewhere (maybe inserting a 0 so I'll need to make it barf every step to debug)

is there more than 1 formula to calculate standard deviation? I am looking over my math and its correct. My output does not match what the garmin says the SD is though.... my manual calculation is matching the powershell 7 measure-output -standarddeviation function when run across the csv so something is wonky and its equation differences.


Garmin Xero C1 Pro chrono - jasper2408 - 01-17-2024

Quote:is there more than 1 formula to calculate standard deviation?

Labradar uses Sample SD and Garmin uses Population SD.

There is a video talking about it here:

[video=youtube;w4ZwuZSePEg]https://www.youtube.com/watch?v=w4ZwuZSePEg[/video]

Don't ask me any questions as that is all I know.:confused:


Garmin Xero C1 Pro chrono - Zeneffect - 01-17-2024

changed up the way it loads files so it processes them 1 at a time instead of im not sure how to explain it... shoving it all in a giant pile and trying to sort from there wasnt working..

Code:
cls Add-Type -AssemblyName System.Windows.Forms function Select-File { [CmdletBinding()] param( [Parameter(ParameterSetName="Single")] [Parameter(ParameterSetName="Multi")] [Parameter(ParameterSetName="Save")] [string]$StartingFolder = [environment]::getfolderpath("mydocuments"), [Parameter(ParameterSetName="Single")] [Parameter(ParameterSetName="Multi")] [Parameter(ParameterSetName="Save")] [string]$NameFilter = "All Files (*.*)|*.*", [Parameter(ParameterSetName="Single")] [Parameter(ParameterSetName="Multi")] [Parameter(ParameterSetName="Save")] [switch]$AllowAnyExtension, [Parameter(Mandatory=$true,ParameterSetName="Save")] [switch]$Save, [Parameter(Mandatory=$true,ParameterSetName="Multi")] [Alias("Multi")] [switch]$AllowMulti ) if ($Save) { $Dialog = New-Object -TypeName System.Windows.Forms.SaveFileDialog } else { $Dialog = New-Object -TypeName System.Windows.Forms.OpenFileDialog if ($AllowMulti) { $Dialog.Multiselect = $true } } if ($AllowAnyExtension) { $NameFilter = $NameFilter + "|All Files (*.*)|*.*" } $Dialog.Filter = $NameFilter $Dialog.InitialDirectory = $StartingFolder [void]($Dialog.ShowDialog()) $Dialog.FileNames } $fit = (Select-File -StartingFolder "C:\" -NameFilter "Garmin FIT Files (*.fit)|*.fit" -AllowMulti) copy $fit .\fit_Temp $fit_temp = get-childitem -Path .\fit_temp | select-object fullname foreach ($fitfile in $fit_temp) { $fit3 = $fitfile.fullname $fit2 = "`"$fit3`"" start-process -filepath '.\java\fittocsv.bat' -argumentlist $fit2 -wait } move-item -path .\fit_temp\*.csv -destination .\results\ $items = get-childitem -Path .\Results\*.csv | select fullname foreach ($item in $items) { $csv1 = $item.fullname | import-csv $csv_data = $csv1 | where 'type' -eq 'data' | where 'local number' -eq 4 $measured = $csv_data.'value 2' | measure-object -average $newNumbers = 0 ForEach ($number in $csv_data) { $newNumbers += [Math]::Pow(($number.'value 2' - $measured.Average), 2) } $stdDev = [math]::Sqrt($($newNumbers / ($measured.Count - 1))) $stddev_fps=$stddev / 304.79999025 foreach ($csv in $csv1) { $time = (([System.DateTimeOffset]::FromUnixTimeSeconds($time_hack)).DateTime.ToLocalTime()).ToString("s") $type = $csv.type $localnumber = $csv."local number" if ($type -eq "Data" -and $localnumber -eq "3") { $min = ($csv."Value 2" / 304.79999025) $max = ($csv."Value 3" / 304.79999025) $average = ($csv."Value 4" / 304.79999025) $shots = $csv."Value 6" $time_hack=$csv."Value 1" $extreme_spread= ($max - $min) Write-host "Session Time/Date:", $time Write-host "# of Shots:", $shots Write-host " " Write-host "Min:", $min Write-host "Max:", $max Write-host "Average:", $average Write-host " " write-host "Standard Deviation:", $stddev_fps Write-host "Extreme Spread:", $extreme_spread write-host " " write-host " " $Session_name = Read-Host -Prompt "Enter Session Name" Write-output "Session Time: $time" | out-file -filepath .\Results\$Session_name.txt -Append Write-output "# of Shots: $shots" | out-file -filepath .\Results\$Session_name.txt -Append Write-output "Min: $min" | out-file -filepath .\Results\$Session_name.txt -Append Write-output "Max: $max" | out-file -filepath .\Results\$Session_name.txt -Append Write-output "Average: $average" | out-file -filepath .\Results\$Session_name.txt -Append Write-Output "Standard Deviation: $stddev_fps" | out-file -filepath .\Results\$Session_name.txt -Append Write-output "Extreme Spread: $extreme_spread" | out-file -filepath .\Results\$Session_name.txt -Append Write-output " " | out-file -filepath .\Results\$Session_name.txt -Append $newNumbers = 0 cls } if ($type -eq "Data" -and $localnumber -eq "4") { $shot_num = $csv.'Value 3' $speed = ($csv.'Value 2' / 304.79999025) $time_hack1=$csv."value 1" $time1 = (([System.DateTimeOffset]::FromUnixTimeSeconds($time_hack1)).DateTime.ToLocalTime()).ToString("s") Write-output " " | out-file -filepath .\Results\$Session_name.txt -Append Write-output "Shot #: $shot_num" | out-file -filepath .\Results\$Session_name.txt -Append Write-output "Speed: $speed" | out-file -filepath .\Results\$Session_name.txt -Append Write-output "Time of Shot: $time1" | out-file -filepath .\Results\$Session_name.txt -Append Write-output " " | out-file -filepath .\Results\$Session_name.txt -Append } } } remove-item .\fit_temp\*.fit


ES and SD are added though the numbers are suspect on SD... need to see what they are doing and how to get them to align. my math is good, but im not sure if i chose the "right" SD equation (i see there are 2?)

TXT output file now looks like this:



Session Time: 2004-01-13T17:18:43
# of Shots: 5
Min: 2627.82816804897
Max: 2678.33341900837
Average: 2650.3905047287
Standard Deviation: 18.7458957133989
Extreme Spread: 50.5052509594034


Shot #: 1
Speed: 2653.21202712867
Time of Shot: 2004-01-16T11:16:12


Shot #: 2
Speed: 2678.33341900837
Time of Shot: 2004-01-16T11:16:22


Shot #: 3
Speed: 2652.38197460868
Time of Shot: 2004-01-16T11:16:29


Shot #: 4
Speed: 2627.82816804897
Time of Shot: 2004-01-16T11:16:39


Shot #: 5
Speed: 2640.20021568882
Time of Shot: 2004-01-16T11:16:48



SOMEONE PLEASE CHECK MY MATH PLEASE PRETTY PLEASE


Garmin Xero C1 Pro chrono - Klem - 01-17-2024

Zene,

Maybe you could contact Garmin when this is done and offer your IP in a business arrangement. I understand the Xero is made in Taiwan, but Garmin is headquartered in Kansas.

The issue of not being able to download usable [CSV] files when plugging into a computer, like Labradar, is fundamental to convincing consumers it is superior. Surely this would be an easy fix with a software update to current users. There is plenty of space on the radar's hard drive for some extra software.


Garmin Xero C1 Pro chrono - jasper2408 - 01-17-2024

Here is the formula used for Population SD in my SD program.
I used these 4 values (1250,1300,1275,1240) so that you can trace them in the formula. 1266.25 is the Mean Average

Quote:Population Standard Deviation (SD)
= sqrt(1/(N) * ((X1-M)^2 + (X2-M)^2 + .... +(XN-M)^2))
= sqrt(1/4 * ((1250-1266.25)^2 + (1300-1266.25)^2 + (1275-1266.25)^2 + (1240-1266.25)^2))
= sqrt(1/4 * ((-16.25)^2 + (33.75)^2 + (8.75)^2 + (-26.25)^2))
= sqrt(542.1875)
= 23.28492

Here is the formula used for Standard SD in my SD program. Don't know if this is Sample SD or not.

Quote:Standard Deviation (SD)
= sqrt(1/(N-1) * ((X1-M)^2 + (X2-M)^2 + .... +(XN-M)^2))
= sqrt(1/(4-1) * ((1250-1266.25)^2 + (1300-1266.25)^2 + (1275-1266.25)^2 + (1240-1266.25)^2))
= sqrt(1/3 * ((-16.25)^2 + (33.75)^2 + (8.75)^2 + (-26.25)^2))
= sqrt(722.9167)
= 26.88711



Garmin Xero C1 Pro chrono - Zeneffect - 01-17-2024

Klem Wrote:Zene,

Maybe you could contact Garmin when this is done and offer your IP in a business arrangement. I understand the Xero is made in Taiwan, but Garmin is headquartered in Kansas.

The issue of not being able to download usable [CSV] files when plugging into a computer, like Labradar, is fundamental to convincing consumers it is superior. Surely this would be an easy fix with a software update to current users. There is plenty of space on the radar's hard drive for some extra software.

I just fixed the get usable CSV direct from device with this script!

feel free to use it

INSTRUCTIONS:

Ensure you have Java installed - It is a requirement from the Garmin SDK that is included in the converter package

DOWNLOAD ENTIRE DIRECTORY FROM MY GOOGLE DRIVE (its small)
https://drive.google.com/drive/folders/1fb_MCyteiMZrcL-gj7DJXlCn-Y_LsGkO?usp=drive_link

Extract the zip file it crated to anywhere on your computer.

Open the "Garmin_CSV_Converter_v2.ps1" file with notepad and add a # to the end of the file and save (the actual symbol # not some random number. This adds a blank comment and makes you owner of the script so it doesnt complain about signing)

Plug in your Garmin Xero C1 Pro

In File Explorer, right click the Garmin_CSV_Converter_v2.ps1 file and select "Run with Powershell"

Another File Explorer window will open, navigate to the .FIT files on the Garmin (example E:\Garmin\Shot_Sessions)

Select all of them and hit "Open"

You will be prompted (in a terminal window) with some session information, enter the session name you desire at this time (just the name, spaces ok, no need to include .txt)

if you chose multiple sessions, the information will update to the next session and you type the new session name again until you are done

check the "Results" folder where the script lives and you should see the TXT outputs there, as well as the raw converted CSV.

*crap*

I have a logic bug I see while reviewing the code. Not a big deal but it will iterate through all the csv files in the results folder to make into text. If you leave them there and add, it will ask about old ones too. For now, clean up csv, ill update in a little bit to fix. It should be easy but I dont feel like doing it right now


Garmin Xero C1 Pro chrono - Zeneffect - 01-17-2024

Code:
?# # Notes: Requires Java # # Copy entire folder from google drive # https://drive.google.com/drive/folders/1fb_MCyteiMZrcL-gj7DJXlCn-Y_LsGkO?usp=drive_link # Connect Garmin Xero C1 Pro to Computer # Run the script (right click + run with powershell) # Navigate to the .FIT files on the device in the pop up and select them, press "Open" button # Name the sessions when prompted in terminal window. Spaces are OK, dont include .txt # # # # Created by ZenEffect cls Add-Type -AssemblyName System.Windows.Forms #ripped this part off of a google search. It creates function for the pop up window to select files function Select-File { [CmdletBinding()] param( [Parameter(ParameterSetName="Single")] [Parameter(ParameterSetName="Multi")] [Parameter(ParameterSetName="Save")] [string]$StartingFolder = [environment]::getfolderpath("mydocuments"), [Parameter(ParameterSetName="Single")] [Parameter(ParameterSetName="Multi")] [Parameter(ParameterSetName="Save")] [string]$NameFilter = "All Files (*.*)|*.*", [Parameter(ParameterSetName="Single")] [Parameter(ParameterSetName="Multi")] [Parameter(ParameterSetName="Save")] [switch]$AllowAnyExtension, [Parameter(Mandatory=$true,ParameterSetName="Save")] [switch]$Save, [Parameter(Mandatory=$true,ParameterSetName="Multi")] [Alias("Multi")] [switch]$AllowMulti ) if ($Save) { $Dialog = New-Object -TypeName System.Windows.Forms.SaveFileDialog } else { $Dialog = New-Object -TypeName System.Windows.Forms.OpenFileDialog if ($AllowMulti) { $Dialog.Multiselect = $true } } if ($AllowAnyExtension) { $NameFilter = $NameFilter + "|All Files (*.*)|*.*" } $Dialog.Filter = $NameFilter $Dialog.InitialDirectory = $StartingFolder [void]($Dialog.ShowDialog()) $Dialog.FileNames } # .FIT file to .CSV - Copies to a "fit_temp" folder first for processing. Does not interact with device except to copy the files to computer first. $fit = (Select-File -StartingFolder "C:\" -NameFilter "Garmin FIT Files (*.fit)|*.fit" -AllowMulti) copy $fit .\fit_Temp $fit_temp = get-childitem -Path .\fit_temp | select-object fullname foreach ($fitfile in $fit_temp) { $fit3 = $fitfile.fullname $fit2 = "`"$fit3`"" # sends the selected files to the bat file that came with the Garmin SDK. Only modification to the .BAT was to remove the "Pause" at the end. FIT files # are processed into CSV by some Garmin SDK Java magic. start-process -filepath '.\java\fittocsv.bat' -argumentlist $fit2 -wait } # gets list of newly created .csv from fit_temp directory for processing $items = get-childitem -Path .\fit_temp\*.csv | select fullname foreach ($item in $items) { # Gets shot data and calculates standard deviation $csv1 = $item.fullname | import-csv $csv_data = $csv1 | where 'type' -eq 'data' | where 'local number' -eq 4 $measured = $csv_data.'value 2' | measure-object -average $newNumbers = 0 ForEach ($number in $csv_data) { $newNumbers += [Math]::Pow(($number.'value 2' - $measured.Average), 2) } $stdDev = [math]::Sqrt($($newNumbers / ($measured.Count - 1))) $stdDevp = [math]::Sqrt($($newNumbers / ($measured.Count))) $stddev_fps=$stddev / 304.79999025 $stddevp_fps=$stddevp / 304.79999025 # Begin CSV to TXT file processing foreach ($csv in $csv1) { $time = (([System.DateTimeOffset]::FromUnixTimeSeconds($time_hack)).DateTime.ToLocalTime()).ToString("s") $type = $csv.type $localnumber = $csv."local number" if ($type -eq "Data" -and $localnumber -eq "3") { $min = ($csv."Value 2" / 304.79999025) $max = ($csv."Value 3" / 304.79999025) $average = ($csv."Value 4" / 304.79999025) $shots = $csv."Value 6" $time_hack=([int]$csv."Value 1" + [int]631065600) $time = (([System.DateTimeOffset]::FromUnixTimeSeconds($time_hack)).DateTime.ToLocalTime()).ToString("s") $extreme_spread= ($max - $min) Write-host "Session Time/Date:" $time Write-host "# of Shots:", $shots Write-host " " Write-host "Min:", $min Write-host "Max:", $max Write-host "Average:", $average Write-host " " write-host "Standard Deviation:", $stddev_fps write-host "Population Standard Deviation:", $stddevp_fps Write-host "Extreme Spread:", $extreme_spread write-host " " write-host " " $Session_name = Read-Host -Prompt "Enter Session Name" Write-output "Session Time/Date: $time" | out-file -filepath .\Results\$Session_name.txt -Append Write-output "Session Name: $session_name" | out-file -filepath .\Results\$Session_name.txt -Append Write-output "# of Shots: $shots" | out-file -filepath .\Results\$Session_name.txt -Append Write-output "Min: $min" | out-file -filepath .\Results\$Session_name.txt -Append Write-output "Max: $max" | out-file -filepath .\Results\$Session_name.txt -Append Write-output "Average: $average" | out-file -filepath .\Results\$Session_name.txt -Append Write-Output "Standard Deviation: $stddev_fps" | out-file -filepath .\Results\$Session_name.txt -Append Write-Output "Population Standard Deviation: $stddevp_fps" | out-file -filepath .\Results\$Session_name.txt -Append Write-output "Extreme Spread: $extreme_spread" | out-file -filepath .\Results\$Session_name.txt -Append Write-output " " | out-file -filepath .\Results\$Session_name.txt -Append $newNumbers = 0 cls } if ($type -eq "Data" -and $localnumber -eq "4") { $shot_num = $csv.'Value 3' $speed = ($csv.'Value 2' / 304.79999025) $time_hack1=([int]$csv."value 1" + [int]631065600) $time1 = (([System.DateTimeOffset]::FromUnixTimeSeconds($time_hack1)).DateTime.ToLocalTime()).ToString("s") Write-output " " | out-file -filepath .\Results\$Session_name.txt -Append Write-output "Shot #: $shot_num" | out-file -filepath .\Results\$Session_name.txt -Append Write-output "Speed: $speed" | out-file -filepath .\Results\$Session_name.txt -Append Write-output "Time of Shot: $time1" | out-file -filepath .\Results\$Session_name.txt -Append Write-output " " | out-file -filepath .\Results\$Session_name.txt -Append } } } # cleanup actions move-item -path .\fit_temp\*.csv -destination .\results\ move-item .\fit_temp\*.fit -destination .\fit_backup

Updated - fixed processing logic so it processes the csv from the temp directory and not results, moved the copied .fit files to backup rather than delete, created empty directory "fit_backups" for backups of raw device data to hard drive. not asking, this is happening and you will thank me later for it.

updated in drive as well.

my apologies for derailing this thread with nerd sh!t but, i think im at the point with this script where i dont really care to improve it. Its about time to redo-it all using 1 little nugget that I used to calculate the SD. I can do this a lot cleaner if I load everything into an array then just have it output the raw csv, a text file, and a "corrected' csv at the same time. User interface would not change.

chose powershell because everyone with a PC has it already. also, afik.. nobody else has tackled this "issue" as completely as I have until now... so.... FIRST!

Maybe ill work on patching in a cleaned up CSV later this week, but for now I like where its at.

The SD imnusing is using the -1 method I believe... more google-fu and not enough caring about math to make the formula myself, just modify the inputs for my needs.



*edit*

The SD differences was driving me up the wall. Added population SD (both are calculated and shown/recorded)

Updated google drive + the above code block. Text file now outputs like this, ill investigate the time bug:


Session Time/Date: 2004-01-16T11:13:36
Session Name: Berf
# of Shots: 5
Min: 2627.82816804897
Max: 2678.33341900837
Average: 2650.3905047287
Standard Deviation: 18.7458957133989
Population Standard Deviation: 16.7668388457128
Extreme Spread: 50.5052509594034


Shot #: 1
Speed: 2653.21202712867
Time of Shot: 2004-01-16T11:16:12


Shot #: 2
Speed: 2678.33341900837
Time of Shot: 2004-01-16T11:16:22


Shot #: 3
Speed: 2652.38197460868
Time of Shot: 2004-01-16T11:16:29


Shot #: 4
Speed: 2627.82816804897
Time of Shot: 2004-01-16T11:16:39


Shot #: 5
Speed: 2640.20021568882
Time of Shot: 2004-01-16T11:16:48