## School Bus Acceleration Characteristics Study

I found a pretty technical study below.

SCHOOL BUS ACCELERATION CHARACTERISTICS
Research was conducted to collect speed, time, and distance data for Type C and D (“full size”) school buses accelerating from a stopped position. Most of the tests were conducted on level terrain. By combining the knowledge of how quickly a school bus can accelerate with assumed speeds of oncoming through-street vehicles, the needed intersection sight distance can be calculated. Another application of the findings is analyzing departure sight distance at railroad grade crossings used by school buses.

This maybe useful for me to estimate the proportion of travel time v.s. dwell time.

Filed under Uncategorized

## Making GTFS query more convenient

I have been spending a lot of time parsing the GTFS database. On the surface it is just a simple CSV files. But to extract useful information from GTFS is often unexpected difficult. For example, find the stops from a bus line in sequential order might sounds like basic thing to do. But it is actually non-trivial with GTFS.

One reason is transit service is more complex it seems. It might seems a bus service just hit all the stops in sequence. But the actual service has a lot of variables. The schedule is often different in weekend compare to weekdays. And so does the exact route that it covers. Sometimes a bus is scheduled to run a short route rather than covering the whole length. In more complex case there can be branching where there is a common main trunk and then the buses split to serve two or more alternative destination.

This is the reason why in GTFS one “route” may associate with multiple “shapes”. To find out what shapes are associate with a route, we will have to make a query like this

SELECT
shape_id
FROM route
JOIN trips
JOIN shape
GROUP BY shape_id;

To find out the stops is even more complex. Here we need to join one more table the stop_times. It is also the biggest tables in the GTFS. So this is also the most computation intensive query to do.

SELECT
shape_id, stop_id
FROM route
JOIN trips
JOIN stop_times
JOIN stops
GROUP BY shape_id, stop_id;

Still most people have a clear concept of what a transit line is where it runs. It shouldn’t be such a pain to compute. A more useful structure should look like below.

    GTFS             More Useful
Structure           Structure

route              line
|                   |
|                   V
|                 route*
|                   | \
|    shape          |  +-> route_shape
|     ^             |  |
|    /              |  +-> route_stops*
|   /               |
V  /                V
trips              trips
|                   |
|        stops      |          stops
|        ^          |
|       /           |
V      /            V
stop_times         stop_times

Here a shift the terminology a bit. The top level entity is a line (i.e. GTFS’ route). This is service that people know of, like a numbered bus line or a metro line. Below that is routes. These are the collection of alternative routes a line may run. The routes are not explicitly represented in GTFS. You can find that by querying all unique shape_id using the first SQL. Another missing piece is the stops. If we can pre-compute all the route_stops using the second SQL once, for the most part we don’t need the giant stop_times table. For applications that do not deal with scheduled time, this is a huge saver. The is one assumption my structure makes though. It is that different lines do not shape that same route. If should be a reasonable assumption. And if there is indeed share route and shape, we should just replicated them as two separate entities.

The original GTFS structure seems to have a transit operator centric view. It allows them maximum flexibility to author and publish their service data. But for application developers, it is not structured for easy traversal. By adding the route and route_stops tables as indicated, it will greatly facilitate the query and operation of transit information.

Filed under Uncategorized

## Expected Wait Time and Variance in Headway

Consider that there are 6 buses in an hour. The time between the arrival of the next bus is called headway. If there are evenly spaced out, the headway will be 10,10,10,10,10,10 minutes. But in a city with unpredictable traffic, the arrival time is often disturbed. What will be the perceived performance in those situation? For example, if the only second bus is delayed by 5 minutes, the headway will be 10,15,5,10,10,10. Or consider a more extreme case where the last three bus bunches together so that after a long gap, they all arrive together within a minutes. That gives 10,10,10,28,1,1. If we just takes the arithmetic mean, it will be 10 in all cases. This number of course does not describe that disturbance it causes. Instead we will calculate the expected wait time over the entire period of time.

Define $W(t)$ as the wait time when a person arrive the station at time t. The $W(t)$ chart looks like a sawtooth. It is highest when the passenger arrive just after a bus has left, and it will be 0 when the passenger arrive . Here $t_{i}$ is when bus i arrives., $h_{i}$ is the headway to the next bus and $T$ is the sum of $t_{i}$.

The expected wait time is given by this formula

$\int_{0}^{T} W(t)P(t)dt$

$P(t)$ is the probability density function of people arrive at time t. We assume people come uniformly. So $P(t)$ is simply $\frac{1}{T}$.

$\frac{1}{T} \sum_{i=1}^{n} \int_{t_{i-1}}^{t_{i}} W(t)dt$

$= \frac{1}{T} \sum_{i=1}^{n} \frac{ {h_{i}}^{2}}{2}$

$= \frac{ \sum h_{i}^{2}} {2T}$

In general communication, it is often more natural to talk about frequency than expected wait time. For example we often say the bus arrive every 10 minutes. But it requires a little bit of math to translate it to 5 minutes of expected wait time. Since the expected wait time is just half of the headway, we can multiple the formula above by to get a effective frequency. We can implement a simple function to calculate the effective frequency below.

>>> def effective_frequency(times):
...         h2 = sum(t*t for t in times)
...         T = sum(times)
...         return float(h2)/T
...
>>> effective_frequency([10,10,10,10,10,10])
10.0
>>> effective_frequency([10,15,5,10,10,10])
10.833333333333334
>>> effective_frequency([10,10,10,28,1,1])
18.1


As expected the last example give a much worst effective frequency 18.1 minutes than the baseline of 10 minutes.

## Relation with Variance

It is interesting to study the relationship between expected wait time and the variance of the headway. This is given by the formula.

$\sigma^2 = \frac {\sum h_i^2 - (\sum h_i)^2/N}{N}$

$\frac { \sigma^2 N } {T} = \frac {\sum h_i^2}{T} - \frac {T^2/N}{T}$

$\frac { \sigma^2 N } {T} + \frac {T}{N} = \frac {\sum h_i^2}{T}$

$\frac { \sigma^2 }{ \mu } + \mu = \frac {\sum h_i^2}{T}$ where $\mu = \frac{T}{N}$

or $\frac {\sigma^2}{\mu} + \mu$ = 2 × Expected Wait Time = effective frequency

There is a very nice interpretation of effective frequency. First of all it is smallest when $\sigma^2$ is 0. That is when the headway are evenly distributed, it will achieve the optimal frequency μ. Secondly effective frequency is larger than μ by $\frac {\sigma^2}{\mu}$. So the variance can be interpret as the penalty above the baseline frequency. In order to minimize wait time, it is necessary to minimize variance.

One implication is how to mitigate missed run. If it is necessary to skip a bus run due to equipment break down or availability of drivers, it is better to redistribute the remaining run evenly than to simply miss a run.

>>> effective_frequency([10,20,10,10,10])
13.333333333333334
>>> effective_frequency([12,12,12,12,12])
12.0


Using the formula above, dropping a run with headway 10,20,10,10,10 gives an effective frequency of 13.3. This is worst than if we can redistribute the remain 5 buses to get a frequency of 12.

Filed under Uncategorized

## Geographic computing – Lat Lon or Lon Lat?

Just encountered a bug in my code where I swapped the order or lat and lon values. It is so easy to apply the wrong order and not finding it. In fact my algorithm works despite I swapped the coordinates. Only a after I notice a slight deviation from the expected result did I start an extensive investigation and identified the mistake.

Is there a standard order to express the coordinate in computing system? It seems the only way to make software reliable is to adopt a consistent order. So I looked at several software system. Here is what I find.

## Lon Lat Order

• GeoJSON – The order of elements must follow x, y, z order (longitude, latitude, altitude, …)
• KML – <gx:coord> A coordinate value consisting of three values for longitude, latitude, and altitude, … Also the values are explicitly tagged as XML element.

There is not a consistent order used in the field. In addition there is also variation of the 3 letter shorthand for longitude – lng v.s. lon. Sigh… No wonder I have messed up.

This is what I’m going to use – lat, lon, so as to follow the verbal convention.

Filed under Uncategorized

## MUNI all door boarding

Muni’s systemwide all-door boarding start in July 2012. Now that 1 month has passed, people should start to get used to being able to board at the back door. Let’s see if we can measure a difference in performance.

Filed under Uncategorized

## Bus Holding Control Strategies

I was thinking about various strategies we can use to control the spacing of bus and even out their headway. Turns out this has been already studied as a discipline of civil engineering.

From Fu and Yang’s paper on Design and Implementation of Bus–Holding Control Strategies with Real-Time Information:

Bus operations in urban environments are often subject to significant variations because of a variety of complex factors such as dynamic and stochastic traffic congestion and passenger demand. These variations, if not offset by control actions, will cause bus bunching—a well-known phenomena contributing to increases in passenger wait time and uncertainty in bus arrival times (1). Controlling bus operations is a way to compensate and reduce the effect of such variations so that the planned headway and schedule can be maintained. Among many bus control strategies, holding control is one of the most effective and common strategies that can be used to regulate bus operations. By holding early-arriving buses, bus headways can be evened out and service reliability improved.

The paper was published in 2002. They believe real-time information system can improve the performance of their model. Of course today system wide real time information are available. It is time to implement these kind of control system to improve the bus performance.

Filed under Uncategorized

## Visualizing Muni Routes

One of the first thing I’m trying to do is to plot Muni routes on the map. Since SFMTA published its transit data in GTFS format I think it is simply a matter of using the coordinates to draw lines. At the end it should produce something like the system map. It turns out the transit data is lot more complex than I expect. After some trial and error, I have produce some reasonably well visualization to show the details of a route.

GTFS describes every trip in a line scheduled to run. It turns out that bus with the same number may in fact run many variation of route. Regular riders may notice some bus runs a shorter route. A good example is the 30 Stockton line.

30 Stockton

I plot each route variation using different color. The small hollow circle marks the origination point and a large solid circle marks the termination point. Furthermore, the width of line is proportion the number of run on such route. Thicker line depicts frequent and often the main route. As we can see, most bus terminate at the blue circle at Divisidero & Chestnut. However, there is also a second frequent terminal at Van Ness and North Point in orange color. If you look more carefully, you may also spot a very thin line terminate near Market St. According to the database, there are 10 trips with the head sign “Union & Columbus” terminate there. It is a curiosity that I have not investigated yet.

38 Geary

Another example that is depicted very successfully is the 38 Geary line. From the graph we can see 4 different routes 38 runs. They split off to terminate at 48th Avenue, VA Hospital or 32nd Ave. Furthermore, a thin red line is an alternate route that run thru VA hospital but terminate at 48th Ave. All routes are fairly thick, meaning each terminal are used almost as frequent. In contrast, the red alternate route is comparatively infrequent. Compare this to system map, I think this depiction of the variation is lot easier to understand.

38 Geary Muni System Map

One of the most helpful technique used is to vary the line width in proportion to the the number of trip run (i.e. the line frequency). For example, the map below shows 14X Mission Express as a thin line. While our first reaction to an express line is that it is fast and wonderful, this alert us that it is also a limited route that runs in commute hours only.

14X Mission Express

This is often a problem with the full system map. It shows a dense web of lines in equal width. Many of these lines are actually special commute hour or late night route that is irrelevant to most riders. Varying the line width help makes the main route stand out form these limited routes.