File: TimeOfArrivalExample.py

package info (click to toggle)
gtsam 4.2.0%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 46,108 kB
  • sloc: cpp: 127,191; python: 14,312; xml: 8,442; makefile: 252; sh: 119; ansic: 101
file content (128 lines) | stat: -rw-r--r-- 3,717 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
"""
GTSAM Copyright 2010-2020, Georgia Tech Research Corporation,
Atlanta, Georgia 30332-0415
All Rights Reserved
Authors: Frank Dellaert, et al. (see THANKS for the full author list)

See LICENSE for the license information

Track a moving object "Time of Arrival" measurements at 4 microphones.
Author: Frank Dellaert
"""
# pylint: disable=invalid-name, no-name-in-module

from gtsam import (LevenbergMarquardtOptimizer, LevenbergMarquardtParams,
                   NonlinearFactorGraph, Point3, Values, noiseModel)
from gtsam_unstable import Event, TimeOfArrival, TOAFactor

# units
MS = 1e-3
CM = 1e-2

# Instantiate functor with speed of sound value
TIME_OF_ARRIVAL = TimeOfArrival(330)


def define_microphones():
    """Create microphones."""
    height = 0.5
    microphones = []
    microphones.append(Point3(0, 0, height))
    microphones.append(Point3(403 * CM, 0, height))
    microphones.append(Point3(403 * CM, 403 * CM, height))
    microphones.append(Point3(0, 403 * CM, 2 * height))
    return microphones


def create_trajectory(n):
    """Create ground truth trajectory."""
    trajectory = []
    timeOfEvent = 10
    # simulate emitting a sound every second while moving on straight line
    for key in range(n):
        trajectory.append(
            Event(timeOfEvent, 245 * CM + key * 1.0, 201.5 * CM, (212 - 45) * CM))
        timeOfEvent += 1

    return trajectory


def simulate_one_toa(microphones, event):
    """Simulate time-of-arrival measurements for a single event."""
    return [TIME_OF_ARRIVAL.measure(event, microphones[i])
            for i in range(len(microphones))]


def simulate_toa(microphones, trajectory):
    """Simulate time-of-arrival measurements for an entire trajectory."""
    return [simulate_one_toa(microphones, event)
            for event in trajectory]


def create_graph(microphones, simulatedTOA):
    """Create factor graph."""
    graph = NonlinearFactorGraph()

    # Create a noise model for the TOA error
    model = noiseModel.Isotropic.Sigma(1, 0.5 * MS)

    K = len(microphones)
    key = 0
    for toa in simulatedTOA:
        for i in range(K):
            factor = TOAFactor(key, microphones[i], toa[i], model)
            graph.push_back(factor)
        key += 1

    return graph


def create_initial_estimate(n):
    """Create initial estimate for n events."""
    initial = Values()
    zero = Event()
    for key in range(n):
        TOAFactor.InsertEvent(key, zero, initial)
    return initial


def toa_example():
    """Run example with 4 microphones and 5 events in a straight line."""
    # Create microphones
    microphones = define_microphones()
    K = len(microphones)
    for i in range(K):
        print("mic {} = {}".format(i, microphones[i]))

    # Create a ground truth trajectory
    n = 5
    groundTruth = create_trajectory(n)
    for event in groundTruth:
        print(event)

    # Simulate time-of-arrival measurements
    simulatedTOA = simulate_toa(microphones, groundTruth)
    for key in range(n):
        for i in range(K):
            print("z_{}{} = {} ms".format(key, i, simulatedTOA[key][i] / MS))

    # create factor graph
    graph = create_graph(microphones, simulatedTOA)
    print(graph.at(0))

    # Create initial estimate
    initial_estimate = create_initial_estimate(n)
    print(initial_estimate)

    # Optimize using Levenberg-Marquardt optimization.
    params = LevenbergMarquardtParams()
    params.setAbsoluteErrorTol(1e-10)
    params.setVerbosityLM("SUMMARY")
    optimizer = LevenbergMarquardtOptimizer(graph, initial_estimate, params)
    result = optimizer.optimize()
    print("Final Result:\n", result)


if __name__ == '__main__':
    toa_example()
    print("Example complete")