A Key in GTSAM is simply a typedef for std::uint64_t. It serves as a unique identifier for variables within a factor graph or values within a Values container. While you can use raw integer keys, GTSAM provides helper classes like Symbol and LabeledSymbol to create semantically meaningful keys that encode type and index information within the 64-bit integer.
import gtsam
from gtsam import Symbol, LabeledSymbol
import numpy as npBasic Usage¶
Keys are typically created using Symbol or LabeledSymbol and then implicitly or explicitly cast to the Key type (integer).
sym = Symbol('x', 0)
key_from_symbol = sym.key() # Or just 'sym' where a Key is expected
print(f"Symbol Key (x0): {key_from_symbol}")
print(f"Type: {type(key_from_symbol)}")
lsym = LabeledSymbol(ord('a'), ord('B'), 1)
key_from_labeled_symbol = lsym.key()
print(f"LabeledSymbol Key (aB1): {key_from_labeled_symbol}")
print(f"Type: {type(key_from_labeled_symbol)}")
# You can also use plain integers, but it's less descriptive
plain_key = 12345
print(f"Plain Integer Key: {plain_key}")
print(f"Type: {type(plain_key)}")Symbol Key (x0): 8646911284551352320
Type: <class 'int'>
LabeledSymbol Key (aB1): 7008163970141913089
Type: <class 'int'>
Plain Integer Key: 12345
Type: <class 'int'>
Key Formatting¶
When printing GTSAM objects that contain keys (like Factor Graphs or Values), you can specify a KeyFormatter to control how keys are displayed. The default formatter tries to interpret keys as Symbols.
print("Default Formatter:")
print(f" Symbol Key: {gtsam.DefaultKeyFormatter(key_from_symbol)}")
print(f" LabeledSymbol Key: {gtsam.DefaultKeyFormatter(key_from_labeled_symbol)}")
print(f" Plain Key: {gtsam.DefaultKeyFormatter(plain_key)}")
# Example of a custom formatter
def my_formatter(key):
# Try interpreting as LabeledSymbol, then Symbol, then default
try:
lsym = gtsam.LabeledSymbol(key)
if lsym.label() != 0: # Check if it's likely a valid LabeledSymbol
return f"KEY[{lsym.string()}]"
except:
pass
try:
sym = gtsam.Symbol(key)
if sym.chr() != 0: # Check if it's likely a valid Symbol
return f"KEY[{sym.string()}]"
except:
pass
return f"KEY[{key}]"
print("Custom Formatter:")
print(f" Symbol Key: {my_formatter(key_from_symbol)}")
print(f" LabeledSymbol Key: {my_formatter(key_from_labeled_symbol)}")
print(f" Plain Key: {my_formatter(plain_key)}")
# KeyVectors, KeyLists, KeySets can also be printed using formatters
key_vector = gtsam.KeyVector([key_from_symbol, key_from_labeled_symbol, plain_key])
# key_vector.print("My Vector: ", my_formatter) # .print() method uses formatter directlyDefault Formatter:
Symbol Key: x0
LabeledSymbol Key: a18577348
Plain Key: 12345
Custom Formatter:
Symbol Key: KEY[x0]
LabeledSymbol Key: KEY[a18577348]
Plain Key: KEY[12345]