Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

A Discrete Motion Model

Open In Colab

For further information on theories and implementations, refer to the robotics book: https://www.roboticsbook.org/

In this notebook, we walk through an simple example of:

  1. Representing discrete random variables in gtsam

  2. Building a bayes net with the discrete random variables

  3. Visualizing the bayes net we built

  4. Doing effecient inference with gtsam FactorGraphs (reducing the inference time from exponential to polynomial)!

Other Installs and Imports

Some of the visualizations below use graphviz. That is not super easy to install except when using conda, in which case it is a one-liner:

conda install -c conda-forge python-graphviz

It is also installed by default on Colab.

Representing Discrete Random Variables

For this simple example, think of a Robot that is moving between different rooms for several seconds. After 1, 2, 3, ... n seconds, the robot wouldn’t be sure where it is any more. So for each timestamp t (1,2,3, ...n), we use a random variable XtX_t to represent the probability of the robot in each room.

We have only 5 rooms ['Living Room', 'Kitchen', 'Office', 'Hallway', 'Dining Room'] variable X can take on. So each XtX_t is a probability distribution over these 5 states. Let’s represent that in gtsam.

The floor plan of a house in which our hypothetical vacuum cleaning robot will operate.

Figure 1:The floor plan of a house in which our hypothetical vacuum cleaning robot will operate.

(0, 5)
(3, 5)

We have just created random variables X1,X2,X3,X4X1, X2, X3, X4. Each one is a discrete variable that has probability of being in each of the room_states.

The printed output we see for X1 and X2 is a tuple (key, cardinality). The key is the gtsam internal representation of the variable. Cardinality in our case is just the number of rooms: 5.

At any time, if you are confused about how to use a function or how to interpret the result, you can run

Help on method discrete in module gtbook.discrete:

discrete(name: str, domain: list[str]) -> tuple[int, int] method of gtbook.discrete.Variables instance
    Create a variable with given name and discrete domain of named values.

    Args:
        name (str): name of the variable.
        domain (list[str]): names for the different values.

    Returns:
        DiscreteKey, i.e., (gtsam.Key, cardinality)

Discrete Series

In the previous example, it’s a bit tedious to create each variable one by one. We can use gtsam.Variables.discrete_series to create a series of discrete variables with the same cardinality.

{1: (6341068275337658369, 5), 2: (6341068275337658370, 5), 3: (6341068275337658371, 5), 4: (6341068275337658372, 5)}
X1: (6341068275337658369, 5)
X4: (6341068275337658372, 5)

Here, we see the keys got much longer, but the object is really exactly the same as what we had above. For more details on how this value is constructed, see here.

Assigning Probabilities

We can now assign probabilities to each variable. Let’s initialize X1 to be in the Living Room with 80% probability, and the rest of the rooms with 5% probability each.

  1. Create a Graph gtsam.DiscreteFactorGraph to record the assignments.

  2. Add the variables to the graph with the assigned probabilities.

Don’t get frustrated by the term FactorGraph, it’s just a graph that holds variables and their probabilities. To learn more about FactorGraphs, and how we use it to perform optimization, view the roboticsbook and the gtsam documentation.

Loading...
Loading...
Loading...

Conditional Probability

Let’s now move between the rooms! Let’s allow the robot to move up, down, left, right. And after taking each action, the room X the robot is in change. To do this, introduce a new variable AA that represent what actions we took, and make next next room the robot with be in Xt+1X_{t+1}, depend (conditional) on the action it takes AtA_t, and where it currently is XtX_t.

Here we focus on building the conditional probability. To learn more about how this simulated robot environment works, visit robotics-book-ch3

Below is the probability table we want to model. Given, current room X1, action A1, what’s the probability of being in each room in X2.

Loading...

It is also possible to represent the probabilities as a list/array to gtsam.DiscreteConditional.

We just need to make sure to force cast the arguments be key: tuple[int, int], parents: gtsam.gtsam.DiscreteKeys, table: list[float]

Loading...

Let’s look at how the graph looks like

Loading...

Sampling from Probability Distribution

If we just want a sample with any prior knowledge about our robot’s location or actions, simply call .sample on the gtsam.DiscreteFactorGraph graph.

Loading...
Loading...

If we do have some additional knowledge. Say we know that:

  1. robot started in the Living Room with 80% probability, 5% in the rest. So X[1] = [0.8, 0.05, 0.05, 0.05, 0.05]

  2. robot took action ‘right’ at time 1

We can condition on that knowledge and sample again. To do this, we do have to build the graph again to incorporate these knowledge.

Loading...

Notice how the variable A[1] is no longer present in our sample. (Since it’s always fixed). If we examine conditional and conditional_up, we can see that we have selected only the rows with A[1] = ‘R’ and completely removed the column A[1].

Loading...
Loading...

Congratulations!

You have built your first discrete bayes net in gtsam, and performed efficient inference with it.