A Grammar for AI-based Parking Sign Understanding

A grammar for parking signs can be used in conjunction with image recognition and text recognition to reason when parking is permitted and for how long.

Street parking in Los Angeles can be a nightmare. Besides the lack of available spaces, signage can be complex and confusing. Often there are multiple signs posted on the same pole that must be read, understood, and reasoned over in order to avoid a citation or towing (the signs in the image at the top of this post are typical). Fortunately, parking sign understanding can be automated with Artificial Intelligence techniques such as image recognition, text recognition, and machine learning. This post describes one piece of a comprehensive solution – a grammar for parking signs – that can be used to generate parsers that apply rules to unstructured sign text to facilitate automated reasoning. I will also show how ANTLR can be be used to generate a parser from the grammar. Grammar for LA parking signs and example photos can be found here on GitHub.

Grammar in this context is defined as the way that we expect words to be arranged on parking signs (for now, we ignore non-alphanumeric symbols such as a P with a line through it). A useful grammar notion commonly used in Computer Science is Extended Backus-Naur form (EBNF).

No Parking for Street Sweeping

One common sign found in Los Angeles and the source of many citations is no parking when there is street sweeping. Several instances of this sign are shown below. Note the following variations:

  1. “NO PARKING” text versus the symbol P with a red circle and line through it
  2. The time range specified by “TO” versus a dash “-“
  3. “12NOON” instead of “12PM”
  4. “STREET SWEEPING” versus “STREET CLEANING”
Street Sweeping Sign

I wrote a program using Apple’s Vision Framework to process these images and extract text from them. The output for these four signs (clockwise from top left) is as follows (note that the output is always uppercase):

  1. NO PARKING 9AM TO 12 NOON MONDAY STREET CLEANING
  2. NO PARKING 8AM – 10AM TUESDAY STREET CLEANING
  3. 8AM TO 10 AM TUESDAY STREET SWEEPING
  4. 9AM TO 12NOON MONDAY STREET SWEEPING

EBNF Grammar

We would like a grammar that covers all of these variations, can be used to distinguish street sweeping signs from other signs, and allow us to understand the parking rules on this street. Taking a bottom-up approach, note that “STREET SWEEPING” and “STREET CLEANING” really mean the same thing, so we can create an EBNF grammar rule for them as follows.

streetSweeping : STREET ( SWEEPING | CLEANING ) ;

The vertical line between SWEEPING and CLEANING means that either of these tokens can match. So if a parser finds the text “STREET SWEEPING” or “STREET CLEANING,” this grammar rule would be executed and create a “streetSweeping” node in the parse tree with the matching tokens as child nodes.

The part of the Parser that matches input text to tokens is called the Lexer. Our grammar would need three lexical rules to support the “streetSweeping” rule as follows.

STREET : 'STREET' ;
SWEEPING : 'SWEEPING' ;
CLEANING : 'CLEANING' ;

The characters between the single quote marks are matched one for one with the input text from the sign and if there is a match, the Lexer creates a node in the parse tree corresponding to the word.

We apply the same approach to identifying the time range on the signs. Some signs specify the range in the form 8AM TO 10AM and others as 8 TO 10AM so we have different rules for “time” and just a plain integer.

timeRange : (time to time) | (INT to time) ;

Since the signs have three conventions for indicating time range (“TO” “THRU” and “-“), we can have a grammar rule for this as well, along with lexical rules to support it.

to : TO | THRU | DASH ;
TO : 'TO' ;
THRU : 'THRU' ;
DASH : '-' ;

For the hours in the time range, we need to handle AM/PM and also NOON and MIDNIGHT. We also need to be able to handle the case when there is a space between the hour number and the AM/PM/NOON/MIDNIGHT and when there is no space (the output of the text recognition software is inconsistent here).

time
  : INT (':' INT )? (am | pm )?
  | twelveNoon
  | twelveMidnight
  ;

twelveNoon : NOON | ('12' NOON) ;
twelveMidnight : MIDNIGHT | ('12' MIDNIGHT) ;

am : 'AM' | ('A.M.') ;
pm : 'PM' | ('P.M.') ;
NOON : 'NOON' ;
MIDNIGHT : 'MIDNIGHT' ;

INT : [0-9]+ ;

Finally, we need rules for the days of week and the words “NO” and “PARKING.” The last rule “WS” is to ignore whitespace.

day : MON | TUE | WED | THU | FRI | SAT | SUN ;
MON : 'MONDAY' | 'MON' ;
TUE : 'TUESDAY' | 'TUE' ;
WED : 'WEDNESDAY' | 'WED' ;
THU : 'THURSDAY' | 'THU' ;
FRI : 'FRIDAY' | 'FRI' ;
SAT : 'SATURDAY' | 'SAT' ;
SUN : 'SUNDAY' | 'SUN' ;

NO : 'NO' ;
PARKING : 'PARKING' ;

WS : [ \t\r\n]+ -> skip ;

The top-level EBNF grammar rule for street sweeping signs can be written as:

streetSweepingSign
    : NO?  PARKING?  timeRange  day  streetSweeping
    ;

The question marks after “NO” and “PARKING” mean that these are optional. That is all the grammar to support this one type of sign. Many of these rules can be reused for other signs (e.g., day, timeRange).

Generating a Parser from the Grammar

ANTLR is a powerful parser generator that operates on an input grammar file to generate all the source code files you need in a target language that can be incorporated into the rest of your application. It also provides command line tools to test your grammar against input text streams. Running the parser generated from the Street Sweeping Sign grammar against the four sign instances creates the following parse trees.

NO PARKING 9AM TO 12 NOON MONDAY STREET CLEANING

NO PARKING 8AM – 10AM TUESDAY STREET CLEANING.

8AM TO 10 AM TUESDAY STREET SWEEPING.

9AM TO 12NOON MONDAY STREET SWEEPING.

Other Types of Parking Signs

There are other types of parking signs that can be found in Los Angeles. The grammar described here for street sweeping signs has been extended to cover all of the instances I’ve encountered (I haven’t driven on every street in LA yet!). This comprehensive parking sign grammar and parser can be used to identify multiple parking signs and reason about whether it is safe to park and for how long. That app is under development and could be the subject of a future post.

Technical Writing – Clarity, Brevity, and Conciseness

Three things to strive for in technical writing are clarity, brevity, and conciseness. These qualities can help ensure effective communication with the audience.

Three things to strive for in technical writing are clarity, brevity, and conciseness. Whether it’s an email, a blog post, or message, keeping these three qualities in mind can help ensure effective communication with the audience. The idiom “Keep it short and sweet” is a helpful reminder and a good start but what is meant by “sweet” in this context?

Technical writing is different from other forms of writing in that its purpose is to convey technical information, often from an expert author to an audience with lesser expertise. Its purpose may also be communicating ideas to a group of technical peers.

Clarity

Writing must be easy to understand or it won’t achieve its purpose. One thing that can lead to misunderstanding is ambiguity. Take for example, the following sentence:

I saw a man on a hill with a telescope.

Who had the telescope? Me, the man, or the hill? Who was on the hill? Me or the man? One technique I use is to read my writings from the perspective of a novice. Pick someone you know who doesn’t have have much knowledge in the area and re-read your piece from their perspective. Where will they be confused? Where can you add clarity?

Brevity

How much of a time commitment are you asking the reader to make? Does your article really need to be that long? How many topics are you covering? Are you going off on tangents? Are you providing unnecessary detail?

Some topics do require more length than others and there is no hard guideline for how long the writing should be. But always keep length in mind and be respectful of the reader.

Conciseness

Conciseness is a measure of the efficiency of your writing – your ability to convey information in as few words as possible. My approach is to not worry about conciseness in my first draft but focus on this during revisions. Often I can cut a significant amount of fat from the piece without losing any valuable content. Be sure you don’t ramble on, go off on unnecessary tangents, or get too wordy.

Keep it Short and Sweet

So what does “sweet” mean in this context? Sweetness in technical writing is a combination of clarity and conciseness. Keeping your technical writing short (brief) and sweet (clear and concise) will help make your readers happy and keep them coming back for more.

Javascript ES6 Demo – Elevator System

An interactive elevator control system and demo implemented in Javascript (ES6) is described. There are links to a demo and the source code.

When interviewing software developers, I like to give them a design problem to work out on a white board. My favorite has been an elevator control system. Everyone should know how elevators are supposed to work, so candidates shouldn’t get bogged down by lack of domain knowledge. Of course, there is no single correct answer and the purpose is really to gain insight into their thought process and how they would approach a problem. I often thought about what my design would look like, but I never followed through and implemented any of my ideas. So, I finally decided to take the plunge and code it to create a Javascript ES6 Demo.

Javascript ES6 Demo

You can see it running here and you can get the source code here on Github.

I decided to implement it in Javascript so it can run in a web browser without any backend. ECMAScript 6 is widely supported now, so I was able to take advantage of some more advanced Javascript language features. IntelliJ was my development environment. Also, the developer tools in Chrome were invaluable.

Architecture

I first considered a distributed architecture with independent controllers for each elevator that “bid” on elevator call requests like an auction (e.g., the elevator that can accept the request with the least cost would get it). The actor model would be a good fit for this approach. But I ended up deciding to implement a centralized control system as an initial solution. I may revisit the distributed architecture in a future implementation.

Metrics and Optimization

What exactly are we trying to optimize? The metrics I used are:

  1. Average Wait Time – the average time a person must wait before being picked up.
  2. Average Travel Time – the average time a person spends inside an elevator.
  3. Average Total Time – the sum of wait and travel time.

I also considered using elevator power consumption as a metric. Modern elevators generate power when they are traveling down which makes this very interesting. But I left this as future work.