Created
September 18, 2025 18:50
-
-
Save contagon/e42f6f55d608ba13c2376ecb7c3c28d5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
\newcommand{\fullref}[1]{\nameref*{#1} (Sec.~\ref*{#1})} | |
\begin{figure*}[t] | |
\centering | |
\begin{tikzpicture}[ | |
node distance = -3mm and 3mm, | |
font = \small, | |
BIGBOX/.style={rectangle, draw=color7!80, fill=color7!20, thick, rounded corners=3pt, minimum height=29mm, minimum width=5.6cm}, | |
BOXBASE/.style={rectangle, thick, rounded corners=2pt, minimum height=10mm, minimum width=1.5cm}, | |
BOX1/.style={BOXBASE, draw=color0!60, fill=color0!5}, | |
BOX2/.style={BOXBASE, draw=color1!60, fill=color1!5}, | |
BOX3/.style={BOXBASE, draw=color2!60, fill=color2!5}, | |
] | |
%Nodes | |
\node (origin) {}; | |
\node (scan) [align=center] {\ac{lidar} Scan}; | |
\node[BOX1] (curvature) [above=11mm of scan, align=center] {Compute \\ Curvature}; | |
\node[BOX1] (extract) [right=of curvature, align=center] {Extract \\ Features}; | |
\node[BOX1] (normals) [right=of extract, align=center] {Compute \\ Normals}; | |
\node[BOX2] (init) [right=0.75cm of normals, align=center] {Initialize}; | |
\node[BOX2] (match) [above right=of init, align=center] {Match \\ Scan}; | |
\node[BOX2] (linopt) [below right =of init, align=center] {Semi-Lin. \\ Optim.}; | |
\node[BOX2] (fullopt) [below right=of match, align=center] {Full \\ Optim.}; | |
% dummy node in the middle to place large figure | |
\node[BOX2, draw=none, fill=none] (middle) [right=of init] {}; | |
\node[BOX3] (keyscan) [right=-3mm and 7mm of fullopt, align=center] {Keyscan \\ Selection}; | |
\node[BOX3] (marg) [right=of keyscan, align=center] {Marg.}; | |
\node[BOX3] (map) [right=of marg, align=center] {Repair \\ Map}; | |
\node[text=white] (output_pose) [below=11mm of marg, align=center] {Pose}; | |
\node[text=white] (output_map) [below=11mm of map, align=center] {Map}; | |
\node (output) at ($(output_pose)!0.5!(output_map)$) {Smoothed Poses \& Map}; | |
\node(corner) at (output-|linopt) {}; | |
\path[->, thick] | |
(scan.north) edge (curvature.south) | |
(curvature.east) edge (extract.west) | |
(extract.east) edge (normals.west) | |
(normals.east) edge (init.west) | |
(init.north) edge[bend left=30] (match.west) | |
($ (match.south) +(0.4cm,0cm) $) edge[bend left=15]($ (linopt.north) +(0.4cm,0cm) $) | |
($ (linopt.north) -(0.4cm,0cm) $) edge[bend left=15]($ (match.south) -(0.4cm,0cm) $) | |
(linopt.east) edge[bend right=20] (fullopt.south) | |
(fullopt.east) edge (keyscan.west) | |
(keyscan.east) edge (marg.west) | |
(marg.east) edge (map.west) | |
(marg.south) edge (output_pose.north) | |
(map.south) edge (output_map.north); | |
\begin{scope}[on background layer] | |
\node[BIGBOX,label=above:{\fullref{sec:feats}}] (big_feature) at (extract) {}; | |
\node[BIGBOX,label=above:{\fullref{sec:icp}}] (big_match) at (middle) {}; | |
\node[BIGBOX,label=above:{\fullref{sec:marg}}] (big_marg) at (marg) {}; | |
\end{scope} | |
\draw[rounded corners, ->, thick] (output.west) -- (corner.center) -- (big_match.south); | |
\end{tikzpicture} | |
\caption{The components that make up the \ac{ours} pipeline as described in Section~\ref{sec:methods}. First, point and planar features are extracted. Next, the pose is initialized, \ac{icp} iterations are performed utilizing a semi-linearized dense optimization over past poses, and a full nonlinear optimization follows. Finally, keyscan management is done, poses are marginalized, and a new map is generated from the smoothed poses.}\label{fig:flow} | |
\end{figure*} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
\begin{figure*}[t] | |
\centering | |
\begin{tikzpicture}[ | |
node distance = 3mm, | |
font = \small, | |
% variable nodes | |
VAR/.style={circle, thick, minimum size=8mm}, | |
VARKEY/.style={circle, thick, minimum size=1.5mm, inner sep=0pt}, | |
KEY/.style={draw=color0!60, fill=color0!5}, | |
LAST/.style={draw=color2!60, fill=color2!5}, | |
RECENT/.style={draw=color1!60, fill=color1!5}, | |
% factor nodes | |
FAC/.style={rectangle, minimum size=1.5mm, inner sep=0pt}, | |
MARG/.style={fill=color4!25, draw=color4!100}, | |
NEW/.style={fill=color3!25, draw=color3!100}, | |
OLD/.style={fill=color7!10, draw=color7!55}, | |
] | |
\pgfmathsetmacro{\numkey}{4} | |
\pgfmathsetmacro{\numrecent}{3} | |
\pgfmathsetmacro{\spacing}{1.5} | |
\pgfmathsetmacro{\numkeyhalf}{\numkey / 2 - 1} | |
% Variable nodes | |
\node[VAR, KEY] (x_k_0) {\(X\)}; | |
\node[VAR, KEY] (x_k_1) [right=of x_k_0] {\(X\)}; | |
\node (key_dots) [right=of x_k_1] {\(\cdots\)}; | |
\node[VAR, KEY] (x_k_2) [right=of key_dots] {\(X\)}; | |
\node[VAR, KEY] (x_k_3) [right=of x_k_2] {\(X\)}; | |
\node[VAR, LAST] (x_r_0) [right=6mm of x_k_3] {\(X\)}; | |
\node[VAR, RECENT] (x_r_1) [right=of x_r_0] {\(X\)}; | |
\node (recent_dots) [right=of x_r_1] {\(\cdots\)}; | |
\node[VAR, RECENT] (x_r_2) [right=of recent_dots] {\(X\)}; | |
\node[VAR, RECENT] (x_r_3) [right=of x_r_2] {\(X\)}; | |
% Marg Factor | |
\node[FAC, MARG] (marg) [below=5mm of x_k_3] {}; | |
\begin{scope}[on background layer] | |
\draw (x_k_0) -- (marg); | |
\draw (x_k_1) -- (marg); | |
\draw (x_k_2) -- (marg); | |
\draw (x_k_3) -- (marg); | |
\draw (x_r_0) -- (marg); | |
\draw (x_r_1) -- (marg); | |
\draw (x_r_2) -- (marg); | |
\end{scope} | |
% Random connections | |
\begin{scope}[on background layer] | |
\path[OLD] (x_r_0) edge[bend left=25] node[FAC, OLD, pos=0.5] {} (x_r_2); | |
\path[OLD] (x_k_0) edge[bend left=25] node[FAC, OLD, pos=0.5] {} (x_r_2); | |
\path[OLD] (x_k_2) edge[bend left=25] node[FAC, OLD, pos=0.5] {} (x_r_2); | |
\path[OLD] (x_k_0) edge[bend left=25] node[FAC, OLD, pos=0.5] {} (x_r_1); | |
\path[OLD] (x_k_1) edge[bend left=25] node[FAC, OLD, pos=0.5] {} (x_r_1); | |
\path[OLD] (x_k_2) edge[bend left=25] node[FAC, OLD, pos=0.5] {} (x_r_1); | |
\path[OLD] (x_k_3) edge[bend left=25] node[FAC, OLD, pos=0.5] {} (x_r_0); | |
\path[OLD] (x_r_0) edge[bend left=25] node[FAC, OLD, pos=0.5] {} (x_r_1); | |
\path[OLD] (x_k_1) edge[bend left=25] node[FAC, OLD, pos=0.5] {} (x_k_2); | |
\path[OLD] (x_k_2) edge[bend left=25] node[FAC, OLD, pos=0.5] {} (x_r_0); | |
\end{scope} | |
% Connected factors to most recent frame | |
\begin{scope}[on background layer] | |
\path (x_k_0) edge[bend left=25] node[FAC, NEW, pos=0.35] {} (x_r_3); | |
\path (x_k_1) edge[bend left=25] node[FAC, NEW, pos=0.35] {} (x_r_3); | |
\path (x_k_2) edge[bend left=25] node[FAC, NEW, pos=0.35] {} (x_r_3); | |
\path (x_k_3) edge[bend left=25] node[FAC, NEW, pos=0.35] {} (x_r_3); | |
\path (x_r_0) edge[bend left=25] node[FAC, NEW, pos=0.35] {} (x_r_3); | |
\path (x_r_1) edge[bend left=25] node[FAC, NEW, pos=0.35] {} (x_r_3); | |
\path (x_r_2) edge[bend left=0] node[FAC, NEW, pos=0.5] {} (x_r_3); | |
\end{scope} | |
% Make the key on the left | |
\node[rectangle, draw=color7!80, fill=color7!3, semithick, rounded corners=2pt, minimum width=33mm, minimum height=25mm] (legend) [above right=-14.5mm and 7mm of x_r_3] {}; | |
\begin{scope}[font=\footnotesize, node distance=2mm] | |
\node[VARKEY, KEY, label=right:Keyscans] (keyscan) [above left=-4mm and -4mm of legend] {}; | |
\node[VARKEY, LAST, label=right:Potential Keyscan] (oldest) [below=of keyscan] {}; | |
\node[VARKEY, RECENT, label=right:Recent Scans] (recent) [below=of oldest] {}; | |
\node[FAC, MARG, label=right:Marginalization Prior] (marg_key) [below=of recent] {}; | |
\node[FAC, NEW, label=right:Newest Matches] (new_match) [below=of marg_key] {}; | |
\node[FAC, OLD, label=right:Previous Matches] (old_match) [below=of new_match] {}; | |
\end{scope} | |
\end{tikzpicture} | |
\caption{Example of the dense factor graph used in \ac{ours}. Shown are keyscans, recent scans, and the recent scan that is being considered to become a keyscan. During semi-linearized optimization, all the previous matches are linearized to use less compute. The newest matches are also recomputed at every \ac{icp} step.}\label{fig:graph} | |
\end{figure*} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Also, there's a number of macros that'll probably cause this to not compile as is. Most of them aren't important for the tikz stuff. Here's the colors though (copied from seaborn's colorblind palette),