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()