Previous posts in the series:
- Car Stats: OBDII + Android + Torque: I introduced the hardware I was using to have this fun.
- Car Stats: Speed vs Instant MPG: I showed what the scatter plot looks like from a single run.
- Car Stats: Automatic Upload to Dropbox: How to get the data off your phone to your computer, easily.
- Car Stats: Where Have I been?: Plotting where we’ve been with Powershell and Windows Forms
Revisiting the second post in this series, but this time:
- All the data collected to date
- Red for uphill, green for downhill, size of point for magnitude
- Blue for mostly level
Analysis:
- The ECU allows idling the engine when coasting, until I get to the last gear, at which time it changes its strategy – it always provides enough fuel to keep the engine purring at a somewhat higher number. Probably because it doesn’t disengage the drivetrain. But it does reduce the gas such that it’s a flat line across at 110 mpg or so. (just enough oomph to prevent the engine from spinning down so fast that the car feels like its stuck in mud, probably.)
- I get better gas mileage around 42 mph – closer to 40mpg. Then it drops down to the 33mpg range as I get up to 55, but pretty much stays there through 75mph.
- When accelerating, the engine opens up in such a way that I get a nice flat line at the bottom of the graph.
Code comments:
- I added a column for altitude change – detected it within a file, I didn’t want to do it outside of the file boundary.
- Sometimes, there’s a trailing comma in the column names.
- I added better Axes to the graph.
Code:
$alldata = @(); $files = gci . -r -include "trackLog.csv" foreach ($file in $files) { $lines = get-content $file "Processing {0}: {1} lines" -f $file, $lines.count # to get around errors with header names not being valid object names $lines[0] = $lines[0] -ireplace '[^a-z,]','' if (-not $lines[0].EndsWith(",")) { $lines[0] = $lines[0] + "," } $lines[0] = $lines[0] + "AltChange" $data = ($lines | convertfrom-csv) for ($i=1; $i -lt $data.Count; $i++) { $prevAlt = [double]$data[$i-1].AltitudeM $Alt = [double]$data[$i].AltitudeM if ($prevAlt -ne $null -and $Alt -ne $null) { $data[$i].AltChange = $Alt - $prevAlt } } $alldata = $alldata + $data } "Total of {0} items" -f $alldata.count $altmeasure = $alldata | measure-object AltChange -min -max -average [void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms.DataVisualization") $chart = new-object System.Windows.Forms.DataVisualization.Charting.Chart $chart.width = 800 $chart.Height = 600 $chart.Left = 40 $chart.top = 30 $chart.Name = "Foo" $chartarea = new-object system.windows.forms.datavisualization.charting.chartarea $chart.ChartAreas.Add($chartarea) $legend = New-Object system.Windows.Forms.DataVisualization.Charting.Legend $chart.Legends.Add($legend) $series = $chart.Series.Add("Series1") $series = $chart.Series["Series1"] #FastPoint ignores color $series.ChartType = [System.Windows.Forms.DataVisualization.Charting.SeriesChartType]::Point $series.IsXValueIndexed = $false $thresh = 0.05 foreach ($data in $alldata) { if ($data.MilesPerGallonInstantMpg -eq $null) { continue } if ($data.GpsSpeedkmh -eq $null) { continue } if ($data.AltChange -eq $null) { continue } $speed = [double]$data.GpsSpeedkmh * 0.621371 $mpg = [double]$data.MilesPerGallonInstantMpg $alt = [double]$data.AltChange if ($alt -lt -$thresh) { # downhill green $color = [System.Drawing.Color]::FromARGB(100,0,255,0) $markersize = 1 - ($alt*2) } elseif ($alt -lt $thresh) { $color = [System.Drawing.Color]::FromARGB(100,0,0,255) $markersize = 2 } else { # uphill red $color = [System.Drawing.Color]::FromARGB(100,255,0,0) $markersize = 1+$alt*2 } if ($markersize -gt 5) { $markersize = 5 } $datapoint = New-Object System.Windows.Forms.DataVisualization.Charting.DataPoint($speed,$mpg) $datapoint.Color = $color $datapoint.MarkerSize = $markersize $series.Points.Add($datapoint) } $chartarea.AxisX.Name = "Speed MPH" $chartarea.AxisX.Interval = 5 $chartarea.AxisX.Minimum = 0 $chartarea.AxisX.IsStartedFromZero=$true $chartarea.AxisY.Name = "MPG" $chartarea.AxisY.Interval = 10 $chartArea.AxisY.Minimum = 0 $chartarea.AxisY.IsStartedFromZero=$true $Form = New-Object Windows.Forms.Form $Form.Text = "PowerShell Chart" $Form.Width = 1100 $Form.Height = 600 $Form.controls.add($Chart) $Chart.Dock = "Fill" $Form.Add_Shown({$Form.Activate()}) $Form.ShowDialog()