Contenido principal

Esta página se ha traducido mediante traducción automática. Haga clic aquí para ver la última versión en inglés.

optimize

Optimizar gráfico de factores

Desde R2022a

Descripción

La función optimize optimiza un gráfico de factores para encontrar una solución que minimice el costo del problema de mínimos cuadrados no lineales formulado por el gráfico de factores. La optimización del gráfico factorial utiliza el solucionador Ceres para la estimación de la covarianza del estado de los nodos, un proceso que implica mayores costos de cálculo y tiempos de estimación más largos a medida que aumenta el número de nodos. Para obtener más información sobre la estimación de covarianza de Ceres-Solver, consulte http://ceres-solver.org/nnls_covariance.html.

Para estimar la covarianza del estado del nodo, optimice con opciones de solucionador personalizadas utilizando el objeto factorGraphSolverOptions que tiene la propiedad StateCovarianceType establecida en uno o más tipos de nodo. Al optimizar gráficos factoriales que requieren estimar la covarianza del estado para una gran cantidad de nodos, considere usar la optimización de ventana deslizante para aumentar la velocidad de optimización al estimar la covarianza del estado para menos nodos a la vez. Para obtener más información sobre la optimización de ventanas deslizantes, consulte Optimice incrementalmente el gráfico de factores mediante la ventana deslizante.

solnInfo = optimize(fg) optimiza el gráfico de factores utilizando las opciones de solucionador predeterminadas, establece los estados de los nodos en los estados optimizados y devuelve la información de la solución resultante.

ejemplo

solnInfo = optimize(fg,poseNodeIDs) optimiza los nodos de pose especificados y cualquier nodo relacionado, excepto los nodos de pose no especificados.

Nota

Al menos uno de los nodos de pose especificados debe cumplir uno o ambos de estos requisitos:

  • Tenga un estado de pose fijo utilizando la función fixNode.

  • Relacionarse con uno o más factores que proporcionan información absoluta sobre el estado:

ejemplo

solnInfo = optimize(___,solverOptions) optimiza el gráfico de factores utilizando las opciones de resolución de gráficos de factores especificadas, además de cualquier combinación de argumentos de entrada de sintaxis anteriores. Por ejemplo, optimize(fg,factorGraphSolverOptions(StateCovarianceType="POSE_SE2")) especifica que optimize debe estimar y almacenar la covarianza del estado del nodo para los nodos de pose SE(2) en el gráfico de factores durante la optimización.

Ejemplos

contraer todo

Cree una matriz de posiciones de los puntos de referencia para usar en la localización y las poses reales del robot para comparar la estimación del gráfico de factores. Utilice la función auxiliar exampleHelperPlotGroundTruth para visualizar los puntos de referencia y la trayectoria real del robot.

gndtruth = [0 0 0; 
            2 0 pi/2; 
            2 2 pi; 
            0 2 pi];
landmarks = [3 0; 0 3];
exampleHelperPlotGroundTruth(gndtruth,landmarks)

Figure contains an axes object. The axes object contains 22 objects of type patch, line, text, scatter. These objects represent Ground Truth, Ground Truth Landmarks.

Utilice la función auxiliar exampleHelperSimpleFourPoseGraph para crear un gráfico de factores que contenga cuatro poses relacionadas por tres factores de dos poses en 2D. Para obtener más detalles, consulte la página del objeto factorTwoPoseSE2.

fg = exampleHelperSimpleFourPoseGraph(gndtruth);

Crear factores punto de referencia

Genere ID de nodo para crear dos ID de nodo para dos puntos de referencia. Los nodos de pose segunda y tercera observan el primer punto de referencia, por lo que deben conectarse a ese punto de referencia con un factor. Los nodos de pose tercero y cuarto observan el segundo punto de referencia.

lmIDs = generateNodeID(fg,2);
lmFIDs = [1 lmIDs(1);  % Pose Node 1 <-> Landmark 1 
          2 lmIDs(1);  % Pose Node 2 <-> Landmark 1
          2 lmIDs(2);  % Pose Node 2 <-> Landmark 2
          3 lmIDs(2)]; % Pose Node 3 <-> Landmark 2

Defina las medidas de posición relativa entre la posición de las poses y sus puntos de referencia en el marco de referencia del nodo de pose. Luego agrega algo de ruido.

lmFMeasure = [0  -1; % Landmark 1 in pose node 1 reference frame 
             -1   2; % Landmark 1 in pose node 2 reference frame
              2  -1; % Landmark 2 in pose node 2 reference frame
              0  -1]; % Landmark 2 in pose node 3 reference frame
lmFMeasure = lmFMeasure + 0.1*rand(4,2);

Cree los factores de referencia con esas medidas relativas y agréguelos al gráfico de factores.

lmFactor = factorPoseSE2AndPointXY(lmFIDs,Measurement=lmFMeasure);
addFactor(fg,lmFactor);

Establezca el estado inicial de los nodos de puntos de referencia en la posición real de los puntos de referencia con algo de ruido.

nodeState(fg,lmIDs,landmarks+0.1*rand(2));

Optimizar gráfico de factores

Optimice el gráfico de factores con las opciones de solver predeterminadas. La optimización actualiza los estados de todos los nodos en el gráfico de factores, por lo que se actualizan las posiciones del vehículo y los puntos de referencia.

rng default
optimize(fg)
ans = struct with fields:
             InitialCost: 0.0538
               FinalCost: 6.2053e-04
      NumSuccessfulSteps: 4
    NumUnsuccessfulSteps: 0
               TotalTime: 1.9908e-04
         TerminationType: 0
        IsSolutionUsable: 1
        OptimizedNodeIDs: [1 2 3 4 5]
            FixedNodeIDs: 0

Visualice y compare resultados

Obtenga y almacene los estados de nodo actualizados para el robot y los puntos de referencia. Luego, trace los resultados, comparando la estimación del gráfico de factores de la trayectoria del robot con ground-truth del robot.

poseIDs = nodeIDs(fg,NodeType="POSE_SE2")
poseIDs = 1×4

     0     1     2     3

poseStatesOpt = nodeState(fg,poseIDs)
poseStatesOpt = 4×3

         0         0         0
    2.0815    0.0913    1.5986
    1.9509    2.1910   -3.0651
   -0.0457    2.0354   -2.9792

landmarkStatesOpt = nodeState(fg,lmIDs)
landmarkStatesOpt = 2×2

    3.0031    0.1844
   -0.1893    2.9547

handle = show(fg,Orientation="on",OrientationFrameSize=0.5,Legend="on");
grid on;
hold on;
exampleHelperPlotGroundTruth(gndtruth,landmarks,handle);

Figure contains an axes object. The axes object contains 17 objects of type patch, line, scatter. One or more of the lines displays its values using only markers These objects represent Opt. Pose, Opt. Pose Edge, Opt. Landmarks, Ground Truth, Ground Truth Landmarks.

Al crear gráficos de factores grandes, es ineficiente volver a optimizar un gráfico de factores completo cada vez que agrega nuevos factores y nodos al gráfico en un nuevo paso de tiempo. Este ejemplo muestra un enfoque de optimización alternativo. En lugar de optimizar un gráfico de factores completo en cada paso de tiempo, optimice un subconjunto o ventana de los nodos de pose más recientes. Luego, en el siguiente paso, deslice la ventana al siguiente conjunto de nodos de pose más recientes y optimice esos nodos de pose. Este enfoque minimiza la cantidad de veces que necesita volver a optimizar partes más antiguas del gráfico de factores.

Cree un gráfico de factores y cargue el archivo MAT sensorData. Este archivo MAT contiene datos del sensor para diez pasos de tiempo.

fg = factorGraph;
load sensorData.mat

Para estimar y almacenar también información de covarianza durante la optimización de la ventana deslizante, cree opciones de solucionador personalizadas que especifiquen que se debe estimar la covarianza de estado para los nodos de pose SE(2).

options = factorGraphSolverOptions(StateCovarianceType="POSE_SE2")
options = 
  factorGraphSolverOptions with properties:

               MaxIterations: 200
           FunctionTolerance: 1.0000e-06
           GradientTolerance: 1.0000e-10
               StepTolerance: 1.0000e-08
              VerbosityLevel: 0
     TrustRegionStrategyType: 1
         StateCovarianceType: Pose_SE2
    InitialTrustRegionRadius: 10000

Establezca el tamaño de la ventana en cinco nodos de pose. Cuanto mayor sea el tamaño de la ventana deslizante, más precisa será la optimización. Si el tamaño de la ventana deslizante es pequeño, es posible que no haya suficientes medidas para que la optimización produzca una solución precisa.

windowSize = 5;

Para cada paso de tiempo:

  1. Genere una nueva ID de nodo para el nodo de pose del paso de tiempo actual.

  2. Obtenga los datos de la pose actual para el paso de tiempo actual.

  3. Genere una ID de nodo para un nodo de punto de referencia recién detectado. Conecte el nodo de pose actual a dos puntos de referencia. Supongamos que el primer punto de referencia que el robot detecta en el paso de tiempo actual es el mismo que el segundo punto de referencia que el robot detectó en el paso de tiempo anterior. Por primera vez, ambos puntos de referencia son nuevos, por lo que debe generar dos ID de puntos de referencia.

  4. Agregue un factor de dos poses que conecte el nodo de pose en el paso de tiempo actual con el nodo de pose del paso de tiempo anterior.

  5. Agregue factores de punto de referencia que creen los ID de nodo punto de referencia especificados al gráfico.

  6. Establezca el estado inicial de los nodos de puntos de referencia y el nodo de pose actual como datos del sensor para el paso de tiempo actual.

  7. Si el gráfico contiene al menos cinco nodos de pose, corrija el nodo de pose más antiguo en la ventana deslizante y luego optimice los nodos de pose en la ventana deslizante. Debido a que tanto las mediciones entre las poses como las mediciones entre las poses y los puntos de referencia son relativas, debe corregir el nodo más antiguo o la solución de optimización puede ser incorrecta. Tenga en cuenta que cuando especifica los nodos de pose, incluye factores que relacionan los nodos de pose especificados con otros nodos de pose especificados o con cualquier nodo que no sea de pose.

for t = 1:10
    % 1. Generate node ID for pose at this time step
    currPoseID = generateNodeID(fg,1);
    % 2. Get current pose data at this time step
    currPose = poseInitStateData{t};

    % 3. On the first time step, create pose node and two landmarks
    if t == 1
        lmID = generateNodeID(fg,2);
        lmFactorIDs = [currPoseID lmID(1); 
                       currPoseID lmID(2)];
    else % On subsequent time steps, connect to previous landmark and create new landmark
        lmIDNew = generateNodeID(fg,1);
        allLandmarkIDs = nodeIDs(fg,NodeType="POINT_XY");
        lmIDPrior = allLandmarkIDs(end);
        lmID = [lmIDPrior lmIDNew];
        lmFactorIDs = [currPoseID lmIDPrior; 
                       currPoseID lmIDNew];
    end

    % 4. After first time step, connect current pose with previous node
    if t > 1
        allPoseIDs = nodeIDs(fg,NodeType="POSE_SE2");
        prevPoseID = allPoseIDs(end);
        poseFactor = factorTwoPoseSE2([prevPoseID currPoseID],Measurement=poseSensorData{t});
        addFactor(fg,poseFactor);
    end

    % 5. Create landmark factors with sensor observation data and add to graph
    lmFactor = factorPoseSE2AndPointXY(lmFactorIDs,Measurement=lmSensorData{t});
    addFactor(fg,lmFactor);

    % 6. Set initial guess for states of the pose node and observed landmarks nodes
    nodeState(fg,lmID,lmInitStateData{t});
    nodeState(fg,currPoseID,currPose);
    
    % 7. Optimize nodes in sliding window when there are enough poses
    if t >= windowSize
        allPoseIDs = nodeIDs(fg,NodeType="POSE_SE2");
        poseIDsInWindow = allPoseIDs(end-(windowSize-1):end);
        fixNode(fg,poseIDsInWindow(1));
        optimize(fg,poseIDsInWindow,options);
    end
end

Obtenga todas las identificaciones de poses y todas las identificaciones de puntos de referencia. Utilice esos identificadores para obtener el estado optimizado de los nodos de pose y de los nodos de puntos de referencia, y obtener la covarianza del estado de los nodos de pose.

allPoseIDs = nodeIDs(fg,NodeType="POSE_SE2");
allLandmarkIDs = nodeIDs(fg,NodeType="POINT_XY");
optPoseStates = nodeState(fg,allPoseIDs);
optLandmarkStates = nodeState(fg,allLandmarkIDs);
poseCov = nodeCovariance(fg,allPoseIDs);

Utilice la función auxiliar exampleHelperPlotPositionsAndLandmarks para trazar la ground-truth de las poses y los puntos de referencia.

initPoseStates = cat(1,poseInitStateData{:});
initLandmarkStates = cat(1,lmInitStateData{:});
exampleHelperPlotPositionsAndLandmarks(initPoseStates, ...
                                       initLandmarkStates)

Figure contains an axes object. The axes object contains 52 objects of type patch, line, text, scatter. These objects represent Ground Truth, Landmarks.

Trace ground-truth de las poses y los puntos de referencia junto con la solución de optimización.

exampleHelperPlotPositionsAndLandmarks(initPoseStates, ...
                                       initLandmarkStates, ...
                                       optPoseStates, ...
                                       optLandmarkStates)

Figure contains an axes object. The axes object contains 54 objects of type patch, line, text, scatter. These objects represent Ground Truth, Landmarks, Opt. Position, Opt. Landmarks.

Tenga en cuenta que puede mejorar la precisión de la optimización aumentando el tamaño de la ventana deslizante o utilizando opciones personalizadas de solver de gráficos de factores.

Argumentos de entrada

contraer todo

Gráfico factorial, especificado como un objeto factorGraph.

Identificadores de los nodos de pose para optimizar dentro del gráfico de factores, especificados como un vector fila de elementos N de números enteros no negativos. N es el número total de nodos de pose para optimizar.

Los nodos de pose especificados por poseNodeIDs deben ser todos del tipo "POSE_SE2", o deben ser todos del tipo "POSE_SE3". Los nodos de pose especificados también deben ser únicos. Por ejemplo, poseNodeIDs no puede ser [1 2 1] porque el ID de nodo 1 no es único en este vector.

Los nodos de pose especificados en el gráfico de factores deben formar un gráfico de factores conectado. Para obtener más información, consulte Conectividad del gráfico de factores.

Opciones de solucionador para el gráfico factorial, especificado como un objeto factorGraphSolverOptions.

Argumentos de salida

contraer todo

Resultados de la optimización, devueltos como una estructura que contiene:

  • InitialCost — Costo inicial del problema de mínimos cuadrados no lineales formulado por el gráfico de factores antes de la optimización.

  • FinalCost — Costo final del problema de mínimos cuadrados no lineales formulado por el gráfico de factores después de la optimización. Un coste final significativamente inferior al coste inicial sugiere una optimización exitosa. Si el costo final está cerca de InitialCost, entonces podría sugerir que los estados iniciales del nodo ya estaban cerca de ser óptimos o que la optimización no pudo mejorar la solución significativamente.

    Nota

    El coste es la suma de términos de error, conocidos como residuos, donde cada residual es una función de un subconjunto de mediciones de factores.

  • NumSuccessfulSteps — Número de iteraciones en las que el solucionador disminuye el costo. Este valor incluye la iteración de inicialización en 0 además de las iteraciones del minimizador.

  • NumUnsuccessfulSteps — Número de iteraciones en las que la iteración es numéricamente inválida o el solucionador no disminuye el costo. Una mayor cantidad de pasos fallidos en comparación con los pasos exitosos podría indicar que el optimizador tiene problemas para converger hacia una solución. Es posible que necesite ajustar los parámetros de optimización, como disminuir el tamaño del paso para garantizar ajustes más pequeños y precisos, o aumentar las iteraciones máximas para brindarle al solucionador más cambios para converger hacia una solución.

  • TotalTime — Tiempo total de optimización del solucionador en segundos.

  • TerminationType — Tipo de terminación como un entero en el rango [0, 2]:

    • 0 — Solver encontró una solución que probablemente sea confiable y cumple con el criterio de convergencia y disminuye el costo después de la optimización.

    • 1 — El solucionador no pudo encontrar una solución que cumpla con el criterio de convergencia después de ejecutar la cantidad máxima de iteraciones. Considere ajustar los parámetros de optimización o modificar las estimaciones iniciales de los estados de los nodos.

    • 2 — El solucionador finalizó debido a un error.

  • IsSolutionUsable — La solución es utilizable si ha convergido o optimize ha alcanzado el número máximo de iteraciones. El valor es 1 (true) si la solución es utilizable y el valor es 0 (false) si la solución no es utilizable.

  • OptimizedNodeIDs — ID de nodos que se optimizaron durante la optimización.

  • FixedNodeIDs — ID de nodos que se repararon durante la optimización en el gráfico de factores o en el gráfico de factores parcial. Tenga en cuenta que estos nodos fijos aún contribuyen a la optimización de otros nodos especificados.

Más acerca de

contraer todo

Sugerencias

  • Antes de optimizar el gráfico de factores o un subconjunto de nodos, utilice la función nodeState para guardar los estados de los nodos en el espacio de trabajo. Si, después de ejecutar la optimización, desea realizar ajustes, puede restablecer los estados del nodo a los estados guardados.

  • Si su optimización no tuvo éxito o dio como resultado estados de nodo inexactos, considere reevaluar los estados de estimación iniciales de los nodos y refinarlos según sea necesario utilizando la función nodeState.

  • Para depurar una optimización parcial de un gráfico de factores, verifique los campos OptimizedNodeIDs y FixedNodeIDs del argumento de salida solnInfo para ver cuáles de los ID de nodo optimizados y cuáles de los nodos fijos contribuyeron a la optimización.

  • Para comprobar si poseNodeIDs forma un gráfico factorial conectado, utilice la función isConnected.

Capacidades ampliadas

expandir todo

Historial de versiones

Introducido en R2022a

expandir todo