All Downloads are FREE. Search and download functionalities are using the official Maven repository.

aima.core.robotics.MonteCarloLocalization Maven / Gradle / Ivy

Go to download

AIMA-Java Core Algorithms from the book Artificial Intelligence a Modern Approach 3rd Ed.

The newest version!
package aima.core.robotics;

import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;

import aima.core.probability.bayes.approx.ParticleFiltering;
import aima.core.probability.domain.FiniteIntegerDomain;
import aima.core.probability.util.ProbUtil;
import aima.core.probability.util.RandVar;
import aima.core.robotics.datatypes.IMclMove;
import aima.core.robotics.datatypes.IMclPose;
import aima.core.robotics.datatypes.IMclRangeReading;
import aima.core.robotics.datatypes.IMclVector;
import aima.core.util.Randomizer;
import aima.core.util.Util;

/**
 * Artificial Intelligence A Modern Approach (3rd Edition): page 982.
*
* *
 * function MONTE-CARLO-LOCALIZATION(a, z, N, P(X'|X, v, w), P(z|z*), m) returns a set of samples for the next time step
 * inputs: a, robot velocities v and w
 *         z, range scan z1,..., zM
 *         P(X'|X,v,w), motion model
 *         P(z|z*), range sensor noise model
 *         m, 2D map of the environment
 * persistent: S, a vector of samples of size N
 * local variables: W, a vector of weights of size N
 *                  S', a temporary vector of particles of size N
 * 
* * Figure 25.9 A Monte-Carlo-Localization algorithm using a range-scan sensor model with independent noise. * The Monte-Carlo-Localization is an extension of a {@link ParticleFiltering} as stated on page 982. * This is true for the functionality but this implementation can not extend the implementation of the ParticleFiltering * as both implementations only contain the actual algorithm as a single method. *

* The update cycle of the algorithm is executed by the method {@code localize} for the given set of samples, move and vector of range readings. * Before calling this method, a set of samples can be generated through the method {@code generateCloud}, which represents the initialization phase of the pseudocode, for the given size N. * This removes the need of specifying the size N on every call of {@code localize} as this information is already contained in the set itself. * The method {@code localize} is divided into these two parts implemented each by a single method: *
    *
  1. {@code applyMove} represents the first line of the update cycle. It moves all samples according to the move / motion model.
  2. *
  3. {@code weightSamples} represents the second to second last line of the update cycle. A vector of weights is created by this method for the given range scans by comparing every range scan to a ray cast with the correspondent sample through the range sensor noise model.
  4. *
* The WEIGHTED-SAMPLE-WITH-REPLACEMENT is implemented by the method {@code extendedWeightedSampleWithReplacement}. This implementation contains the addition of a cutoff value. All particles having a weight below this cutoff are ignored. *

* It is possible to reduce the steps needed for the localization by tweaking the sample count and the parameter {@code cutOff}. *

* @author Arno von Borries * @author Jan Phillip Kretzschmar * @author Andreas Walscheid * * @param

a pose implementing {@link IMclPose}. * @param an n-1-dimensional vector implementing {@link IMclVector}, where n is the dimensionality of the environment. This vector describes the angle between two rays in the environment. * @param a movement (or sequence of movements) of the robot implementing {@link IMclMove}. * @param a range measurement implementing {@link IMclRangeReading}. */ public final class MonteCarloLocalization

, V extends IMclVector, M extends IMclMove, R extends IMclRangeReading> { private static final String SAMPLE_INDEXES_NAME = "SAMPLE_INDEXES"; private final IMclMap map; private final Randomizer randomizer; private RandVar sampleIndexes; private double weightCutOff; /** * @param map an instance of a class implementing {@link IMclMap}. * @param randomizer a {@link Randomizer} that is used for re-sampling. */ public MonteCarloLocalization(IMclMap map, Randomizer randomizer) { this.map = map; this.randomizer = randomizer; } /** * Sets the minimum weight of the particles. * @param cutOff the minimum weight below which the corresponding particle gets removed during the {@code resample()} step. Set to zero when in doubt. */ public void setWeightCutOff(double cutOff) { this.weightCutOff = cutOff; } /** * Applies a move to the samples, creating a new {@link Set}. * @param samples the samples the move will be applied to. * @param move the move to be applied to the samples. * @return a new set of size N containing the moved samples. */ protected Set

applyMove(Set

samples, M move) { Set

newSamples = new LinkedHashSet

(); for(P sample: samples) { newSamples.add(sample.applyMovement(move.generateNoise())); } return newSamples; } /** * Weights the samples by a given vector of range scans. * @param samples the samples to be weighted. * @param rangeReadings the vector containing all range scans. * @return a vector of weights of size N. */ protected double[] weightSamples(Set

samples, R[] rangeReadings) { Iterator

samplesIterator = samples.iterator(); double[] w = new double[samples.size()]; for(int j=0;j extendedWeightedSampleWithReplacement(Set

samples, double[] w) { int i = 0; for(;i weightCutOff) break; } if(i >= samples.size()) return generateCloud(samples.size()); /*If all particleCloud are below weightCutOff, generate a new set of samples, as we are lost.*/ /*WEIGHTED-SAMPLE-WITH-REPLACEMENT:*/ double[] normalizedW = Util.normalize(w); Set

newSamples = new LinkedHashSet

(); Object[] array = samples.toArray(new Object[0]); for(i=0; i < samples.size(); i++) { final int selectedSample = (Integer) ProbUtil.sample(randomizer.nextDouble(),sampleIndexes,normalizedW); newSamples.add(((P) array[selectedSample]).clone()); } return newSamples; } /** * This method is the initialization phase of the algorithm. It has to be called to generate a set of samples of count N. * @param N the count of samples. * @return a set containing N samples. */ public Set

generateCloud(int N) { Set

samples = new LinkedHashSet

(); Integer[] indexes = new Integer[N]; for(int i=0;i localize(Set

samples, M move, R[] rangeReadings) { if(samples == null) return null;/*initialization phase = call generateCloud*/ Set

newSamples = applyMove(samples, move);/*motion model*/ double[] w = weightSamples(newSamples, rangeReadings);/*range sensor noise model*/ newSamples = extendedWeightedSampleWithReplacement(newSamples, w); return newSamples; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy