Thank You And Goodbye

The practical course Internet of Things at TU Dresden has nearly finished. The final presentation (PDF: Final_Presentation) took place on Friday. We would like to thank our students for participating the course and developing an impressive solution based on multiple components and techniques to measure the quality of road surfaces. We are looking forward to bring the results to bear. We are still in talks with different companies that allow us to test the outcomes in a wider range. Stay tuned!

Advertisements

Final User Interface

During the last two weeks I worked on the final design of the user interface.

You are now able to watch the sensor data in 3 seperated graphs for each test ride. You can select the different values, you want to see by enabling or disabling them via checkboxes. In addition to that you’re now able to switch between raw and matched view, either visualized as lines, or as points. Because of having only two quality categories, we removed the five quality-selectors I had introduced some time ago in a blog post.

All in all the UI has now its full functionality. 😉

First threshold to classify “good” and “bad” roads

After visualizing the sensor data of a 25 time frame (from our first test drive) which contained both, good and bad quality roads we decided that the road quality can be extracted by only using the “z-acceleration” – at least for a first threshold to classify between two simple qualities: “good/okay” and “(really) bad”.

(The green section in the first chart marks a good quality road, the blue sections a “normal” quality road and the red section a “(really) bad” quality road.)
accel-and-marks

For references: charts for gyroscope and rotation data:
gyro

rota

 

Finding a first threshold

Then we combined our road quality notes of the first test drive with the “Z-acceleration” data of the whole test drive and decided to use 1.4 as a threshold to differentiate between regular quality and “pothole measurements”:

21:49 “bad road”
received_2015-06-24_19-42-13

20:52 “really bad road”
received_2015-06-24_18-51-17

21:05 “quite good road”
received_2015-06-24_19-00-38

21:23 & 21:25 “really bad road”
received_2015-06-24_19-18-59

First test drive in real life!

On wednesday evening Armin, Stephan and me went out for a test drive. For this purpose we rented a car from a local car sharing company called teilAuto. We met at the informatics faculty building and set up the whole measurement hardware.

IMG_20150624_203240782

During the test drive Armin was watching the gathering of the data on his laptop. He also checked the hardware regulary.

IMG_20150624_220016416

We tried to cover a large part of Dresden und also passed some possible difficulties like roundabouts, passing the same junction/streets several times or driving through a tunnel. Except some problems with the timestamps and a short blackout because of too high acceleration everything went pretty fine.

Now it is time to evaluate these data!

Creating the Front-End

As we move along with the project, its time to look at the Front-End. We want a clear, responsive design that is accessible for the normal user.
We use Leaflet, MapBox, jQuery and Chart.js to visualise our data.
This is the first draft and there is still a lot to do. We need to take a look on what features are needed, and how to implement them in a fast way.
The groundwork is there, now we need to handle the communication with the server and find a good way to visualise quality and state of the roads.

Bildschirmfoto - 09.06.2015 - 00:58:14

Bildschirmfoto - 09.06.2015 - 01:00:55

Project overview

As various tasks are being worked on for a long time separately, I now want to give a short overview about what is the current state and which tasks are coming next.

The web server

What’s done

  • Importing dummy data from a csv file in a predefined format
  • Map matching each imported point
  • Storing data as GeoJSON Points using MongoDB
  • REST API which allows us to query
    • all points in a certain bounding box
    • all points in a circle with a max and min distance to the center
    • points with a filter which only returns each n-th element

Whats next

  • Aggregate points in database based on distance between each other. Means: Somehow group points which are located nearby each other.
  • Enable intelligent querying to limit number of points to a useful number. Currently to much points are returned for the browser to render live (e.g each 10nth of 400 000 = 40 000)
  • Create API Endpoint for storing data via POST request or Websocket, depending on which solution seems to be more efficient for our huge size of data

The front end

What’s done

  • Dynamically fetch data for given bounding box from webserver
  • Apply filter in order to only display each n-th point
  • Reload points if displayed area changes

What’s next

  • Reload only missing areas, not all points after moving the map
  • Create lines out of points in order to allow a more seamless display of the measured data (this may need to be done on the web server, still needs to be figured out)
  • Add more UI Elements in order to display further data from the collected measurements

The Raspberry PIs

What’s done

  • Hardware setup, including
    • Adding sensors to the GPIO ports of the RPIs
    • Setting up a battery powered environment
  • Startup script in order to setup all dependencies, config files and run the application when powering the RPI
  • Fetching the time from the GPS sensor and updating the system time from it
  • Collecting GPS measurements and storing it in a CSV file
  • Collecting measurements from other RPIs sensors and sending it to “central” RPI via websocket

What’s next

  • Transmit data to web server via HTTP/POST or websocket
  • Test setup “in whole” in order to make sure everything works together
  • Fine tuning concerning the way the data is stored and transmitted, e.g. match the different CSV-formats
  • Create a script checking whether internet connection is available and whether the server is reachable, in order to send data to it
  • Add wifi module to enable wireless transmission of data

Visualising collected data with Leaflet

Task

After storing and querying measured data as GeoJSON in a database, we now want to display and evaluate this data in a web application. This process consists of two parts: a back end to fetch the data from the database in a RESTful way, and a front end to process and display the data.

Back end

The backend is implemented in NodeJS using the express framework and mongoDB. This article will not cover how to implement a web server, see here for a good tutorial.

We want to get data within a given bounding box, so the URI to get the data will be

http://yourwebserver.tld/api/geojson/area/:nelat/:nelng/:swlat/:swlng',

where nelat, nelngswlat, swlng are coordinates of the bounding box in the WGS84 format.

A GET-Request to this URI will then send us a response as an array of points in the given area. A additional URL parameter filter will furthermore allow us to only retrieve each n-th element.

Example http://localhost:8080/api/v1/geojson/area/50.867186428774374/9.78358268737793/50.84009382168376/9.65998649597168?filter=10

[
  {
    "type": "Feature",
    "properties": {
      "speed": 37.25,
      "measurement": 10,
      "quality": "Green"
    },
    "geometry": {
      "type": "Point",
      "coordinates": [
        9.660391807556152,
        50.84591293334961
      ]
    }
  },
  {
    "type": "Feature",
    "properties": {
      "speed": 25.25,
      "measurement": 6,
      "quality": "Green"
    },
    "geometry": {
      "type": "Point",
      "coordinates": [
        9.735342979431152,
        50.8564567565918
      ]
    }
  },
  {
    "type": "Feature",
    "properties": {
      "speed": 33.5,
      "measurement": 6,
      "quality": "Red"
    },
    "geometry": {
      "type": "Point",
      "coordinates": [
        9.704183578491211,
        50.853240966796875
      ]
    }
  }
]

Front end

The front end will be implemented using the leaflet framework in combination with https://github.com/calvinmetcalf/leaflet-ajax in order to fetch data from a web server and directly display it.

This combination allows us to define a url and dynamically load all points in the current bounding box, using leaflets map.on('moveend', addPointsFromDB) event.

The function addPointsFromDB then first gets the current bounding box:

var nelat = map.getBounds().getNorthEast().lat;
var nelng = map.getBounds().getNorthEast().lng;
var swlat = map.getBounds().getSouthWest().lat;
var swlng = map.getBounds().getSouthWest().lng;

Defines a filter value based on the current zoom level, in order to only display each n-th point when zoomed away:

var filter = 0;

var z = map.getZoom();

var zoomFilter = {
'14' : 0,
'13' : 2,
'12' : 8,
'11' : 15,
'10' : 20,
'9' : 30,
'8' : 70
};

if(z > 14) filter = 0;
else if (z < 8 ) filter = 70;
else filter = zoomFilter[z];

and fetches the data from the given url. Each Feature gets drawn on the map as a circleMarker on the marker layer. Therefore any old layers need to be removed, before each Feature gets added:

    var url = 'http://localhost:8080/api/v1/geojson/area/'+nelat+'/'+nelng+'/'+swlat+'/'+swlng+'?filter='+filter;
    var pointLayer = new L.GeoJSON.AJAX(url, {
        
        middleware: function(data) {  
            //Clear existing marker layer
            //The whole bounding box of the map gets redrawn
            markers.clearLayers();
            return data;
        },
        
        pointToLayer: function (feature, latlng) {

            var geojsonMarkerOptions = {
                radius: 3,
                fillColor: feature.properties.quality,
                color: feature.properties.quality,
                weight: 1,
                opacity: 1,
                fillOpacity: 0.9
            };

            var circleMarker = L.circleMarker(latlng, geojsonMarkerOptions);
            var content = feature.properties.quality
            circleMarker.bindPopup(content);
            circleMarker.addTo(markers);
            return L.circleMarker(latlng, geojsonMarkerOptions);
        }

    }).addTo(markers);

Result

Adding very little of CSS already leads to beautiful results:

Visualisation

 

RoadStar | Crowd-based Assessment of Road Surface Quality

Background

Bad road surfaces are are physical stress for drivers and car. They reduce the travelling comfort, increase the fuel consumption and  create noise pollution. As a result,  the measurement and repairing of roads is a regular task for road traffic departments everywhere. Detecting bad surfaces is mostly done with specialised measurement cars. This procedure is often both expensive and time consuming, and creates a financial problem. As a result, repairs are often delayed or not done at all.

Thanks to research in the area of cyberphysical systems, it is nowadays possible to integrate measurement devices in any car. Using a crowdsourcing approach, one could give away these measurement devices and then collect and evaluate all the measured data in a central instance. This data could then, for example, be used to create better road models which would allow faster repairs, or to improve navigation to avoid “bumpy roads”.

Goal of Roadstar

Goal of this project is it to develop and test a system, which allows simple measurement of road surface data while driving, and creating a system for storage and evaluation of this data afterwards. Common hardware, such as Rasperry PIs, gyro- and gps-sensors should therefore be combined into a portable measurement system.

Core concepts which should be implemented, are the synchronisation, transmission, storage and basic evaluation of the measured sensor data. With these sensors, data should continuously be measured at different points of the car. The collected data then should be synchronised and transmitted to a central server.

On the server, the data should be classified using existing algorithms, and transformed into a form which can be displayed on a simple web frontend.