Main Content

Using Pretrained DLCHOMP Optimizer in Unseen Obstacle Environment

Since R2024a

This example shows how to use a pretrained DLCHOMP optimizer to work with a target spherical obstacle environment that is different from the environment the optimizer was trained on.

In this example, you'll start with a dlCHOMP object that has a network that has been pretrained for a robot with an appropriate obstacle set. To use this pretrained network on a new obstacle set, you'll need to retrain the network using transfer learning.

In this example it is assumed that the pretrained dlCHOMP optimizer is trained for the target robot kukaIiwa7 as specified by its RigidBodyTree property, has the desired basis point set encoder as specified by its BPSEncoder property and outputs the desired number of waypoints as specified by its NumWaypoints property. However the training dataset spherical obstacle environment that the dlCHOMP optimizer was trained on, as specified by its associated dlCHOMPDataOptions object, does not match the desired target spherical obstacle environment. Since the pretrained dlCHOMP object's RigidBodyTree, the BPSEncoder and the NumWaypoints properties meet the desired requirements, but its corresponding dlCHOMPDataOptions object does not, transfer learning can still be performed by generating a new dataset using a new dlCHOMPDataOptions object that meets the desired requirements and then retraining the pretrained dlCHOMP object on this new dataset. If you would like to change the number of predicted waypoints instead, refer to the Using Pretrained DLCHOMP Optimizer to Predict Higher Number of Waypointsexample.

To try out pretrained networks for other robots, see Pretrained Optimizers.

This example uses a new dlCHOMPDataOptions object to generate a new dataset for a pretrained dlCHOMP optimizer and then retrains it on this new dataset.

Background

Transfer learning is a deep learning approach in which a model that has been trained for one task is used as a starting point for a model that performs a similar task. Updating and retraining a network with transfer learning is usually much faster and easier than training a network from scratch.

Transfer learning is a popular technique because:

  • It enables you to train models with less labeled data by reusing popular models that have already been trained on large data sets.

  • It can reduce training time and computing resources. With transfer learning, the weights are not learned from scratch because the pretrained model has already learned the weights based on previous learnings.

For more information about transfer learning, see What Is Transfer Learning?.

Download Pretrained DLCHOMP Optimizer

The pretrained DLCHOMP optimizer to be downloaded was trained for the target robot kukaIiwa7 as specified by its RigidBodyTree property and has the desired basis point set encoder as specified by its BPSEncoder property. Since the RigidBodyTree and the BPSEncoder properties meet the desired requirements, but the obstacle environment that it was trained on does not match the environment we desire, transfer learning can be performed by retraining the network on a new dataset representative of the desired target environment. This will be covered in the next section.

For now, download a pretrained DLCHOMP optimizer trained for the kukaIiwa7 robot. Also obtain the dlCHOMPDataOptions object that was used to generate the training dataset used to train this pretrained optimizer.

dlCHOMPComponent = "rst/data/dlCHOMP/R2024a";
pretrainedDLCHOMPFilename = "kukaIiwa7DLCHOMPTrained.zip";
disp("Downloading previously trained kukaIiwa7 dlCHOMP optimizer (46 MB)...");
Downloading previously trained kukaIiwa7 dlCHOMP optimizer (46 MB)...
pretrainedDLCHOMPFolder = exampleHelperDownloadData(dlCHOMPComponent,pretrainedDLCHOMPFilename);
pretrainedDLCHOMPMATPath = fullfile(pretrainedDLCHOMPFolder,"trainedDLCHOMP.mat");  
loadedData = load(pretrainedDLCHOMPMATPath,"robotName","trainedDLCHOMP","trainInfo","trainOptions","trainLossType","dataOptions");
pretrainedRobotName = loadedData.robotName;
pretrainedDLCHOMP = loadedData.trainedDLCHOMP;
pretrainedTrainInfo = loadedData.trainInfo;
pretrainedTrainOptions = loadedData.trainOptions;
pretrainedTrainLossType = loadedData.trainLossType;
pretrainedDataOptions = loadedData.dataOptions;

As can be seen in the training plot above, the pretrainedDLCHOMP optimizer took 1500 iterations to get trained, and hence converge, from scratch.

Specify Target Spherical Obstacle Environment

This example assumes knowledge of the dlCHOMPDataOptionsobject property values that represent the target environment of interest. For more information on obtaining and determining the correct dlCHOMPDataOptions object property values, see Train Deep-Learning-Based CHOMP Optimizer for Motion Planning.

Create a new dlCHOMPDataOptions object by specifying the data generation options that represent the target spherical obstacle environment of interest.

desiredDataOptions = dlCHOMPDataOptions(...
    "RadiusRangeOfObstacles",[0.0500 0.2000],...
     "CountRangeOfObstacles",[10 15],...
       "MinDistanceFromBase",0.2100)
desiredDataOptions = 
  dlCHOMPDataOptions with properties:

    RadiusRangeOfObstacles: [0.0500 0.2000]
     CountRangeOfObstacles: [10 15]
       MinDistanceFromBase: 0.2100
                NumSamples: 2000
           ValidationSplit: 0.2000
              RandomStream: 'threefry'
                      Seed: 0

Check Training Dataset Representing Target Spherical Obstacle Environment

Finally, for a given dlCHOMP optimizer, you can generate its training data using a corresponding dlCHOMPDataOptions object. This data options object represents the target spherical obstacle environment that the dlCHOMP optimizer is trying to learn motion planning for. So there is a need to check if the data that was used to train the pretrained dlCHOMP optimizer matches the desired target environment. For this, check the following properties that affect the environment complexity of the dlCHOMPDataOptions object that was used to train the pretrained dlCHOMP optimizer:

  • RadiusRangeOfObstacles

  • CountRangeOfObstacles

  • MinDistanceFromBase

Notice that these properties of a dlCHOMPDataOptions object are writable post object creation.

Let's compare these property values for the chosenDataOptions and pretrainedDataOptions objects.

radiusRangeOfObstaclesMatch = isequal( ...
    desiredDataOptions.RadiusRangeOfObstacles,pretrainedDataOptions.RadiusRangeOfObstacles)
radiusRangeOfObstaclesMatch = logical
   1

countRangeOfObstaclesMatch = isequal( ...
    desiredDataOptions.CountRangeOfObstacles,pretrainedDataOptions.CountRangeOfObstacles)
countRangeOfObstaclesMatch = logical
   0

minDistanceFromBaseMatch = isequal( ...
    desiredDataOptions.MinDistanceFromBase,pretrainedDataOptions.MinDistanceFromBase)
minDistanceFromBaseMatch = logical
   1

environmentChecksPass = radiusRangeOfObstaclesMatch && countRangeOfObstaclesMatch && minDistanceFromBaseMatch
environmentChecksPass = logical
   0

As can be seen above, the countRangeOfObstaclesMatch check does not pass which leads the environment check to fail. This indicates that the pretrainedDLCHOMP optimizer was trained on a spherical obstacle environment that does not match the desired spherical obstacle environment.

Since the pretrainedDLCHOMP optimizer matches all the desired objectives except for the desired target spherical obstacle environment of interest, a new small dataset can be generated for retraining the optimizer to meet this one last unsatisfied objective.

Generate Training Dataset Matching Desired Environment

First, modify the dlCHOMPDataOptions properties of the chosenDataOptions object that affect environment diversity and the training versus validation data set splits.

As explained in the Background section, there is a need to generate a much smaller training dataset as compared to what the pretrainedDLCHOMP object was trained on.

For this, decrease the training dataset size in the desiredDataOptions object to be much smaller than that of the pretrainedDataOptions object.

For this, set the NumSamples property of desiredDataOptions to be a tenth of that of pretrainedDataOptions which amounts to 500 as compared to 5000 data samples. For more information on these properties, see dlCHOMPDataOptions.

desiredDataOptions.NumSamples = pretrainedDataOptions.NumSamples/10
desiredDataOptions = 
  dlCHOMPDataOptions with properties:

    RadiusRangeOfObstacles: [0.0500 0.2000]
     CountRangeOfObstacles: [10 15]
       MinDistanceFromBase: 0.2100
                NumSamples: 500
           ValidationSplit: 0.2000
              RandomStream: 'threefry'
                      Seed: 0

Keep 20% of the generated data set for validation and the rest for training. To do this set the ValidationSplit property to 0.2.

desiredDataOptions.ValidationSplit = 0.2;

Now, execute the following code snippet to generate the 500 samples. Note that this takes 1 hr on a Windows 10 system with 48 GB of RAM. Hence, this dataset is downloaded by default as generateData is set to false below.

If you would like to wait for data generation, set generateData to true. Otherwise, set generateData to false.

generateData = false;

If generateData is false, download the required data. Otherwise, generate the data.

dataSamplesFolder = "allData";
if generateData == false
    dataSamplesFilename = "kukaIiwa7DataForRetrainingDLCHOMPToNewEnv.zip";
    disp("Downloading data for retraining kukaIiwa7 dlCHOMP optimizer (144 MB)...");
    dataSamplesFolder = exampleHelperDownloadData(dlCHOMPComponent, ...
        dataSamplesFilename, 'DataFolder',dataSamplesFolder);
    validIndices = 1:floor(desiredDataOptions.ValidationSplit * desiredDataOptions.NumSamples);
    trainIndices = (numel(validIndices)+1):desiredDataOptions.NumSamples;
    validDS = dlCHOMPDatastore(dataSamplesFolder,validIndices);
    trainDS = dlCHOMPDatastore(dataSamplesFolder,trainIndices);
else
    seed = 100;
    rng(seed,"twister");
    [trainDS,validDS] = generateSamples(pretrainedDLCHOMP,desiredDataOptions,dataSamplesFolder);
end
Downloading data for retraining kukaIiwa7 dlCHOMP optimizer (144 MB)...

Retrain Pretrained DLCHOMP Optimizer

Let's retrain the pretrainedDLCHOMP optimizer object using the new data that was obtained.

We can use the same training options object pretrainedTrainOptions by setting its ValidationData property to the new validDS we obtained earlier. We keep the other properties the same.

trainOptions = pretrainedTrainOptions;
trainOptions.ValidationData = validDS;

Use the loss type pretrainedTrainLossType that was used to train the pretrainedDLCHOMP object.

Now, retrain the pretrainedDLCHOMP optimizer object using the training datastore trainDS, loss type pretrainedTrainLossType and the training options trainOptions. Note that this takes 1 hr using 8 parallel workers on a Windows 10 system with 48 GB of RAM. Hence, this retrained object is downloaded by default as doRetraining is set to false below.

If you want to retrain the object yourself, set doRetraining to true. Otherwise, set doRetraining to false.

doRetraining = false;

If doRetraining is false, download a new pretrained dlCHOMP optimizer object. Otherwise, retrain the existing object.

if doRetraining == false
    retrainedDLCHOMPFilename = "kukaIiwa7DLCHOMPRetrainedForNewEnv.zip";
    disp("Downloading previously retrained kukaIiwa7 dlCHOMP optimizer (44 MB)...");
    retrainedDLCHOMPFolder = exampleHelperDownloadData(dlCHOMPComponent,retrainedDLCHOMPFilename);
    retrainedDLCHOMPMATPath = fullfile(retrainedDLCHOMPFolder,"retrainedDLCHOMP.mat");
    load(retrainedDLCHOMPMATPath,"retrainedDLCHOMP","retrainInfo");
else
    retrainInfo = trainDLCHOMP(pretrainedDLCHOMP,trainDS,pretrainedTrainLossType,trainOptions);
    retrainedDLCHOMP = pretrainedDLCHOMP;
end
Downloading previously retrained kukaIiwa7 dlCHOMP optimizer (44 MB)...

As can be seen above, the dlCHOMP optimizer converged much faster while training, within about 150 iterations, which is much smaller than the nearly 1500 iterations that were needed to train the pretrained dlCHOMP optimizer from scratch as was shown in the training plot under the Download Pretrained DLCHOMP Optimizer section above. This indicates that the network had already learned weights based on previous learnings and simply had to be tuned to work for the new target spherical obstacle environment.

Infer Using Retrained DLCHOMP Optimizer

Now that the retrained optimizer is available, we can use it for inference on an unseen target environment of interest.

Generate One Unseen Target Environment

Let's generate an unseen target environment using the same dlCHOMPDataOptions object were chosen for generating the training and validation data sets to ensure the same environment complexity. However, change the properties that affect the environment diversity to ensure that an unseen data sample is generated.

First, to generate only 1 data sample, set the NumSamples property to 1 and set the ValidationSplit property to 0 respectively.

desiredDataOptions.NumSamples = 1;
desiredDataOptions.ValidationSplit = 0;

Next, to ensure an unseen data sample is generated, change the Seed value to differ it from the one used when generating the training and validation data sets used to train the optimizer. Since we used the default Seed value of 0 then, let's use a value of 500 now.

desiredDataOptions.Seed = 500;

Choose a new location for saving the generated unseen sample.

folderForUnseenData = "unseenData";

Generate an unseen target environment.

rng(desiredDataOptions.Seed,"twister");
testDS = retrainedDLCHOMP.generateSamples(desiredDataOptions,folderForUnseenData);
------------------------
Starting data generation
[1/1] Data Samples Written	|	┃┃┃┃┃┃┃┃┃┃┃┃┃┃┃┃┃┃┃┃ 100.00% complete	|	
Total Run Time: 00:00:01 secs
Estimated Time Remaining: 00:00:00 secs
------------------------
filePathToUnseenSample = resolve(testDS.FileSet).FileName(1);
[unseenStart,unseenGoal,unseenObstacles,chompTrajectory] = exampleHelperExtractDataFromDLCHOMPSample(filePathToUnseenSample);

Infer On Unseen Target Environment

Make the retrainedDLCHOMP optimizer aware of the unseen spherical obstacles.

retrainedDLCHOMP.SphericalObstacles = unseenObstacles;

Finally, use the retrainedDLCHOMP optimizer for inference on this unseen target environment.

[optimWptsDLCHOMP,optimTptsDLCHOMP,solninfoDLCHOMP] = retrainedDLCHOMP.optimize(unseenStart,unseenGoal);

Let's visualize this trajectory in an animated fashion.

% Create new figure
figure

% Show animated robot trajectory
ax = show(retrainedDLCHOMP,unseenStart);
title("dlCHOMP Optimized End-Effector Trajectory in Unseen Target Environment");
axis(ax,"equal")
exampleHelperShowAnimatedRobotTrajectory(ax,retrainedDLCHOMP.RigidBodyTree,optimWptsDLCHOMP);

Figure contains an axes object. The axes object with title dlCHOMP Optimized End-Effector Trajectory in Unseen Target Environment, xlabel X, ylabel Y contains 111 objects of type patch, line. These objects represent world, iiwa_link_0, iiwa_link_1, iiwa_link_2, iiwa_link_3, iiwa_link_4, iiwa_link_5, iiwa_link_6, iiwa_link_7, iiwa_link_ee, iiwa_link_ee_kuka, iiwa_link_0_mesh, iiwa_link_1_mesh, iiwa_link_2_mesh, iiwa_link_3_mesh, iiwa_link_4_mesh, iiwa_link_5_mesh, iiwa_link_6_mesh, iiwa_link_7_mesh, iiwa_link_0_coll_mesh, iiwa_link_1_coll_mesh, iiwa_link_2_coll_mesh, iiwa_link_3_coll_mesh, iiwa_link_4_coll_mesh, iiwa_link_5_coll_mesh, iiwa_link_6_coll_mesh, iiwa_link_7_coll_mesh.

Conclusion

In conclusion, you learned how to determine if a pretrained dlCHOMP optimizer can be used in a target spherical obstacle environment. You also learned how to retrain this pretrained dlCHOMP optimizer meant for one type of spherical obstacle environment for use in a different type of spherical obstacle environment. Finally, you used this retrained dlCHOMP optimizer for motion planning in an unseen target obstacle environment.

See Also

Related Topics