Continuing from the last post, I created a (Windows Phone) mobile application that is largely based from this article and modified for use with the proposed system. The UI will be very simple and will display the core metrics as defined in AirVantage application model.
The key metrics that I wanted to capture are :
- Current Speed
- Distance traveled
- Travel Time
- Idle Time
- CO2 footprint
The code logic for the application is pretty straightforward as outlined below.
And translated as code below:
private void UpdateMetrics(Geocoordinate geocoordinate) { int thisTick = Environment.TickCount; /* Update travel time */ int tickLapsed = thisTick - _timeLastPositionChanged; _travelTime = _travelTime.Add(TimeSpan.FromMilliseconds(tickLapsed)); double speed = geocoordinate.Speed.HasValue ? geocoordinate.Speed.Value : 0; /* Speed is reported in meters/sec */ if(geocoordinate.Speed.Value < MIN_SPEED || geocoordinate.Speed.HasValue == false) { /* speed is below minimum speed or has not been reported, this could indicate we are at idle */ _idleTime = _idleTime.Add(TimeSpan.FromMilliseconds(tickLapsed)); } double travel = Haversine.Distance( new Position() { Latitude = geocoordinate.Point.Position.Latitude, Longitude = geocoordinate.Point.Position.Longitude }, new Position() { Latitude = _lastGeocoordinate.Point.Position.Latitude, Longitude = _lastGeocoordinate.Point.Position.Longitude }, DistanceType.Kilometers); _distanceTravelled += travel; double co2 = ((_distanceTravelled / KM_PER_LITER) * CO2_KG_PER_LITER); _co2 = co2; /* Update UI components */ Map.Center = geocoordinate.Point; Speed.Text = "Speed: " + (speed * 3.6).ToString("0.0") + " kph"; TravelTime.Text = "Travel Time: " + _travelTime.ToString(@"hh\:mm\:ss"); IdleTime.Text = "Idle Time: " + _idleTime.ToString(@"hh\:mm\:ss"); Distance.Text = "Distance: " + _distanceTravelled.ToString("0.0") + " km"; if (co2 < 1) Co2Level.Text = "CO2: " + (co2 * 1000).ToString("0") + " gms"; else Co2Level.Text = "CO2: " + (co2).ToString("0.000") + " kg"; double distanceSinceLastRender = Haversine.Distance( new Position() { Latitude = _lastGeoPoint.Latitude, Longitude = _lastGeoPoint.Longitude }, new Position() { Latitude = geocoordinate.Point.Position.Latitude, Longitude = geocoordinate.Point.Position.Longitude }, DistanceType.Kilometers); /* add data point to map line */ if (distanceSinceLastRender > 0.010) { _geoPositions.Add(geocoordinate.Point.Position); _mapLine.Path = new Geopath(_geoPositions); _lastGeoPoint = geocoordinate.Point.Position; } _timeLastPositionChanged = Environment.TickCount; _lastGeocoordinate = geocoordinate; }
As you may have observed, idle time starts ticking when the speed is below the minimum value of 10kph. The distance traveled is calculated at each geographical position changed using Haversine formula. CO2 level is calculated as described in previous post where KM_PER_LITER and CO2_KG_PER_LITER are set as 12.5 and 2.22 respectively.
When the Stop button has been tapped, the monitoring flag is reset and the data is sent to AirVantage. Immediately after writing the code, I tested it by driving around the block, and verified the data has been successfully saved in AirVantage.
Fascinated by the data, I started using the app today and monitored how much my footprint is when dropping the kids to school.
Looking at this data, I spent almost 44% travelling in idle (10kph or less) most of it is due to traffic. My average speed is 16.85kph on a 50kph road, seems like its better to cycle (if possible) during this time than travelling on car. Also, 1.35kg of CO2 was produced for that particular trip, given 5 days of school x 2 trips per day x 10 weeks (ave) per term x 4 terms a year ends up 540 kg of CO2 annually!
Update:
As I was not able to track a couple trips to work using this app, I thought of automating the process such that the app will auto-launch when the phone is placed in the cradle. This ensures that the application starts immediately at the beginning of each trip. This was done by programming an NFC sticker that will launch the app and pass an argument. The app has to be slightly modified as well to handle the argument. A short clip has been added in this post to see how it works.
Top Comments