129 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Python
		
	
	
			
		
		
	
	
			129 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Python
		
	
	
| """
 | |
| 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")
 |