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.

Planificación de rutas mediante MPNet para sistemas automatizados de valet parking

Desde R2024b

Este ejemplo demuestra cómo utilizar una red de planificación de movimiento (MPNet) previamente entrenada para planificar rutas casi óptimas de una manera computacionalmente eficiente para un sistema de estacionamiento autónomo. En este ejemplo, generará un conjunto diverso de mapas a partir de una imagen de escena de estacionamiento para crear un conjunto de datos para entrenar MPNet. Luego, utilizará el MPNet entrenado para planificar rutas en un nuevo escenario de servicio de valet parking.

El resto de este ejemplo demuestra los pasos involucrados en la planificación de rutas para un sistema de estacionamiento autónomo.

  • Generar escenario de valet parking: genere automáticamente varios mapas para la planificación de rutas a partir de una imagen de una escena de estacionamiento utilizando la función helperParkingLotMap. Puede especificar el número de lugares de estacionamiento que estarán presentes en los mapas de estacionamiento generados. La función elige aleatoriamente la ubicación para la cantidad especificada de lugares de estacionamiento. Para agregar estados de inicio y objetivo al escenario, utilice la función helperSampleStartGoal. Además, puedes utilizar la función helperSampleStartGoal para seleccionar una maniobra de entrada o salida para el escenario.

  • Generar conjunto de datos de entrenamiento: genere un conjunto de datos de entrenamiento mediante la función helperGenerateParkingLotDataset. La función utiliza las funciones helperParkingLotMap y helperSampleStartGoal para generar una cantidad deseada de mapas y pares de inicio y objetivo, respectivamente, para la planificación de rutas. El conjunto de datos generado consta de varias rutas óptimas calculadas para múltiples mapas con diferentes lugares de estacionamiento. Se generan las rutas óptimas para los escenarios de entrada y salida. En un escenario de entrada, la ruta se planifica desde un punto de entrada fuera del estacionamiento hasta un lugar de estacionamiento, mientras que en un escenario de salida, la ruta se planifica desde un lugar de estacionamiento hasta un punto de salida fuera del estacionamiento.

  • Crear y entrenar MPNet: cree una red de aprendizaje profundo MPNet utilizando el objeto mpnetSE2. Entrene la red en el conjunto de datos de entrenamiento generado utilizando la función trainnet.

  • Planificar ruta usando MPNet entrenado: crea un planificador de ruta MPNet usando el objeto plannerMPNet. Dado un mapa de prueba, utilice el método plan del objeto plannerMPNet para calcular la ruta entre los estados inicial y objetivo utilizando el MPNet preentrenado.

Generar escenario de valet parking

Lea una imagen de escena de estacionamiento en el espacio de trabajo MATLAB. La imagen de entrada debe ser una imagen binaria.

inputScene = imread("parkingScene.bmp");

Especifique el tamaño de celda para crear un mapa de ocupación binario de la imagen de la escena de estacionamiento. El tamaño de la celda determina la resolución del mapa de ocupación.

cellSize = 0.5;

Crea un mapa de ocupación binario con una resolución de 1/cellSize.

inputMap = binaryOccupancyMap((inputScene),Resolution=1/cellSize);

Especifique el centro de los posibles lugares de estacionamiento dentro del mapa.

xLoc = [14, 18.5, 23, 27.25, 31.5, 36, 40.5, 44.75, 49, 53.5, 57.75];
yLoc = [46.5, 28.25, 21.5, 3.5];
[x,y] = meshgrid(xLoc,yLoc);

Muestra la imagen de la escena de estacionamiento y el mapa de ocupación binario. Trace las coordenadas x y y del centro de los lugares de estacionamiento en el mapa.

fig = figure(Position=[0 0 600 300]);
subplot(Position=[0 0 0.4 1],Parent=fig)
imshow(inputScene)
title("Parking Scene Image")
subplot(Position=[0.5 0 0.5 1],Parent=fig)
show(inputMap)
hold on
plot(x,y,'*r')
hold off

Especifique el número de plazas de estacionamiento que se ocuparán en el mapa modificado.

numParkedSpots = 10;

Genere un mapa de estacionamiento modificado con la cantidad especificada de lugares estacionados usando la función helperParkingLotMap. La función selecciona aleatoriamente qué espacios del estacionamiento estarán ocupados y coloca vehículos de tres tamaños diferentes en esos lugares. Al variar los tamaños de los vehículos, la función crea escenarios más realistas y diversos para entrenar la red de aprendizaje profundo MPNet.

[outputMap,parkingStates] = helperParkingLotMap(inputMap,numParkedSpots,cellSize,xLoc,yLoc);

Muestra el mapa de estacionamiento generado.

figure
show(outputMap)

Genere un escenario de entrada o salida con estados de inicio y objetivo aleatorios utilizando la función helperSampleStartGoal. Para un escenario de entrada, especifique la variable scenario como "entry". Para un escenario de salida, especifique la variable scenario como "exit". La función helperSampleStartGoal genera mapas para escenarios de entrada y salida con igual probabilidad. Para lograr esto, la función utiliza la función rand para generar un número aleatorio distribuido uniformemente entre 0 y 1. Si el número aleatorio generado es mayor que 0,5, el escenario se establece en "entry"; de lo contrario, se establece en "exit". Esto garantiza que ambos escenarios sean igualmente probables, cada uno con una probabilidad del 50%.

scenario = "entry";
[start,goal] = helperSampleStartGoal(parkingStates,scenario);

Muestra el escenario de servicio de valet parking generado con el vehículo ego utilizando la función helperPlotEgoVehicle.

hold on
helperPlotEgoVehicle(start,DisplayName='start')
helperPlotEgoVehicle(goal,DisplayName='goal')
legend
hold off
title("Parking Valet Scenario")

Generar conjunto de datos de entrenamiento

Descargue y descomprima un archivo que contenga el conjunto de datos de entrenamiento.

URL = "https://ssd.mathworks.com/supportfiles/nav/data/parkingLotDataset.zip";
filename = "./parkingLotDataset.zip";
websave(filename,URL);
unzip parkingLotDataset.zip

El conjunto de datos descargado contiene 200.000 rutas óptimas calculadas utilizando la función helperGenerateParkingLotDataset. A continuación se ofrece una descripción general de las funcionalidades clave de la función helperGenerateParkingLotDataset.

  • La función helperGenerateParkingLotDataset utiliza la función auxiliar helperParkingLotMap para generar una cantidad deseada de mapas modificados para la planificación de rutas.

  • La función selecciona aleatoriamente los estados de inicio y destino de cada mapa utilizando la función auxiliar helperSampleStartGoal para planificar la ruta.

  • La función utiliza el espacio de estados Reeds-Shepp y el planificador de rutas RRT* para calcular las rutas factibles y casi óptimas.

  • Para acelerar la generación del conjunto de datos, la función utiliza procesamiento paralelo si tiene Parallel Computing Toolbox ™; de lo contrario, utiliza procesamiento en serie.

  • La función guarda las rutas casi óptimas generadas en un archivo .mat para uso futuro en el entrenamiento de MPNet.

Como alternativa, para generar su propio conjunto de datos, configure la variable generateData en true y especifique la cantidad de rutas óptimas que desea generar para el conjunto de datos de entrenamiento.

generateData = false;
if generateData==true
    numPaths = 20;
    helperGenerateParkingLotDataset(inputMap,cellSize,xLoc,yLoc,numPaths);

    files = dir("data/parkingValetPath*.mat");
    numSamples = length(files);
    dataset = cell(numSamples,1);
    for i = 1:length(files)
        load(fullfile(files(i).folder,files(i).name),'pathStates')
        dataset{i,1} = pathStates;
    end
    dataset = cell2table(dataset,'VariableNames',"Path");
    save("MyParkingDataset","dataset")
end

Cargar y visualizar el conjunto de datos de entrenamiento

Cargue el conjunto de datos de entrenamiento descargado en el espacio de trabajo MATLAB ® y visualice muestras de las rutas óptimas almacenadas en él.

load("parkingLotDataset.mat","dataset");
figure
for i=1:4
    subplot(2,2,i)
    % Select a random sample
    ind = randi(height(dataset));
    % Get path from Path column of the table
    pathStates = dataset(ind,:).Path{1};
    % Get start and goal states from the path
    start = pathStates(1,:);
    goal = pathStates(end,:);
    show(inputMap);
    hold on
    plot(pathStates(:,1),pathStates(:,2),plannerLineSpec.path{:})
    plot(start(1),start(2),plannerLineSpec.start{:})
    plot(goal(1),goal(2),plannerLineSpec.goal{:})
    hold off
end
legend(Position=[0.85 0.002 0.13 0.11]);

Crear MPNet

Cree un objeto MPNet para el espacio de estados SE(2) utilizando el objeto mpnetSE2.

mpnet = mpnetSE2;

Establezca la propiedad StateBounds del objeto mpnetSE2 en los límites del mapa de entrada utilizado para generar el conjunto de datos.

x = inputMap.XWorldLimits;
y = inputMap.YWorldLimits;
theta = [-pi pi];
stateBounds = [x; y; theta];
mpnet.StateBounds = stateBounds;

Especifique los pesos para cada variable del espacio de estado utilizando la propiedad LossWeights del objeto mpnetSE2. Para valores de peso más altos, la red tarda más épocas en converger. Para este ejemplo, los valores de peso para cada variable de espacio de estado deben ser distintos de cero.

mpnet.LossWeights = [100 100 50];

Establezca el valor de la propiedad EncodingSize en cero porque MPNet se entrenará utilizando datos generados desde un único entorno de mapa.

mpnet.EncodingSize = [0 0];

Preparar datos para el entrenamiento

Realice una ampliación de datos agregando versiones invertidas de las rutas al conjunto de datos. Esto ayuda a aumentar el tamaño y la diversidad de las muestras de entrenamiento. El aumento de datos aumenta la robustez de la red para la planificación bidireccional.

flippedPaths = cellfun(@(x) flipud(x), dataset.Path, UniformOutput=false);
dataset = [dataset.Path; flippedPaths];

Divida el conjunto de datos en datos de entrenamiento y validación en una proporción de 80:20. El conjunto de entrenamiento, que comprende el 80% de los datos, se utiliza para entrenar la red minimizando la pérdida de entrenamiento. El 20% restante de los datos forma el conjunto de validación, que se utiliza para monitorear la pérdida de validación durante el proceso de entrenamiento.

split = 0.8;
numTrain = ceil(split*height(dataset));
trainData = dataset(1:numTrain,1);
validationData = dataset(numTrain+1:end,1);

Preprocesar los datos de entrenamiento y validación. La función mpnetPrepareData preprocesa los datos y los almacena en un almacén de datos. La función mpnetPrepareData reemplaza la variable de espacio de estado theta con sus componentes coseno y seno y normaliza las variables de espacio de estado x y y para que se encuentren dentro del rango [0, 1].

dsTrain = mpnetPrepareData(trainData,mpnet);
dsValidation = mpnetPrepareData(validationData,mpnet);

Tren MPNet

Utilice la función trainnet para entrenar el MPNet. El entrenamiento de esta red puede llevar mucho tiempo dependiendo del hardware que utilice. Establezca el valor doTraining en true para entrenar la red.

doTraining = false;

Especifique trainingOptions para entrenar la red de aprendizaje profundo:

  • Configure el optimizador "adam".

  • Establezca MiniBatchSize para el entrenamiento en 2048.

  • Baraja los dsTrain en cada época.

  • Establezca MaxEpochs en 50.

  • Establezca ValidationData en dsValidation y ValidationFrequency en 2000.

if doTraining
    options = trainingOptions("adam",...
        MiniBatchSize=2048,...
        MaxEpochs=50,...
        Shuffle="every-epoch",...
        ValidationData=dsValidation,...
        ValidationFrequency=2000,...
        Plots="training-progress");
    % Train network
    [net,info] = trainnet(dsTrain,mpnet.Network,@mpnet.loss,options);
    % Update Network property of mpnet object with net
    mpnet.Network = net;
end

En este ejemplo, utilizará un MPNet previamente entrenado para calcular las predicciones. Cargue un archivo .mat que contenga la red entrenada previamente. La red se ha entrenado en el conjunto de datos descargado, archivo ParkingLotDataset.mat.

if ~doTraining
    load("parkinglotTrainedMPNET.mat","trainedNetwork")
    mpnet.Network = trainedNetwork;
end

Planificar ruta con MPNet entrenado

Genere un mapa de estacionamiento nuevo y modificado a partir del mapa de entrada utilizado para generar el conjunto de datos de entrenamiento. Especifique el número de plazas de aparcamiento como 15.

numParkedSpots = 15;
[map,parkingStates] = helperParkingLotMap(inputMap,numParkedSpots,cellSize,xLoc,yLoc);

Establezca el radio de inflado en 1. Inflar el mapa para tener en cuenta la geometría del vehículo durante la planificación de la ruta.

inflationRadius = 1;
mapInflated = copy(map);
inflate(mapInflated,inflationRadius)

Genere un estado inicial y objetivo aleatorio utilizando la función helperSampleStartGoal. También puede especificar si el escenario debe ser un escenario de entrada o de salida.

 
scenario = "Entry";
[start,goal] = helperSampleStartGoal(parkingStates,scenario);

Cree un espacio de estado Reeds-Shepp con un radio mínimo del vehículo de 4. Debe utilizar el mismo espacio de estado tanto para el entrenamiento como para la inferencia.

stateSpace = stateSpaceReedsShepp(stateBounds);
stateSpace.MinTurningRadius = 4.0;

Cree un validador de estado utilizando la función validatorOccupancyMap para validar estados según un mapa de ocupación. Establezca la distancia de validación en 0,1. Asigna el mapa inflado al validador de estado para garantizar que las rutas planificadas eviten obstáculos de manera efectiva.

stateValidator = validatorOccupancyMap(stateSpace);
stateValidator.ValidationDistance = 0.1;
stateValidator.Map = mapInflated;

Cree un planificador de rutas MPNet utilizando el validador de estado y el MPNet entrenado previamente. Establezca el número máximo de estados aprendidos que generará el planificador de rutas MPNet en 20.

mpnetPlanner = plannerMPNET(stateValidator,mpnet);
mpnetPlanner.MaxLearnedStates = 20;

Planifique una ruta entre los estados inicial y objetivo utilizando el planificador de rutas MPNet.

[mpnetPath,solutionInfo] = plan(mpnetPlanner,start,goal);

Si se encuentra una ruta, interpórela para aumentar su resolución y suavidad.

if solutionInfo.IsPathFound
    mpnetPathCopy = copy(mpnetPath);
    interpolate(mpnetPathCopy,100)
end

Traza la ruta planificada.

figure
show(map)
hold on
if solutionInfo.IsPathFound
    plot(mpnetPathCopy.States(:,1),mpnetPathCopy.States(:,2),plannerLineSpec.path{:})
    plot(start(1),start(2),plannerLineSpec.start{:})
    plot(goal(1),goal(2),plannerLineSpec.goal{:})
    title(strcat("Path Planning using MPNet for ",scenario," Scenario"))
else
    plot(mpnetPath.States(:,1),mpnetPath.States(:,2),plannerLineSpec.path{:})
    plot(start(1),start(2),plannerLineSpec.start{:})
    plot(goal(1),goal(2),plannerLineSpec.goal{:})
    title("Path Not Found")
end

Muestra los estados aprendidos, los estados de baliza y los estados clásicos calculados por el planificador de rutas MPNet.

displaySolutionInfo = true;
if displaySolutionInfo
    lstate = plannerLineSpec.state(DisplayName="Learned states",MarkerSize=3);
    cstate = plannerLineSpec.state(DisplayName="Classical states",MarkerSize=3,MarkerFaceColor="green",MarkerEdgeColor="green");
    bstate = plannerLineSpec.state(MarkerEdgeColor="magenta",MarkerSize=7,DisplayName="Beacon states",Marker="^");
    plot(solutionInfo.LearnedStates(:,1),solutionInfo.LearnedStates(:,2),lstate{:})
    plot(solutionInfo.ClassicalStates(:,1),solutionInfo.ClassicalStates(:,2),cstate{:})
    plot(solutionInfo.BeaconStates(:,1),solutionInfo.BeaconStates(:,2),bstate{:})
end
legend(Location="bestoutside")
hold off

Consulte también

| | | | | (Deep Learning Toolbox) | (Deep Learning Toolbox) | | |

Temas