我目前正在根据他们的指南在 Matlab 中实现 amcl 。使用 amcl 函数时 getParticles 可以在此处找到定义它说所有粒子具有相同的权重。为什么会出现这种情况,如何解决?我正在从运行 ROS 的 VM 接收过滤器的信息,并且粒子确实会聚,这让我认为粒子的权重是正确的。(否则它们不应该收敛,对吧?)。已经坚持了一段时间了,所以需要所有的帮助。
load officemap.mat
show(map)
odometryModel = odometryMotionModel;
odometryModel.Noise = [0.2 0.2 0.2 0.2];
rangeFinderModel = likelihoodFieldSensorModel;
rangeFinderModel.SensorLimits = [0.45 8];
rangeFinderModel.Map = map;
% Query the Transformation Tree (tf tree) in ROS.
tftree = rostf;
waitForTransform(tftree,'/base_link','/base_scan');
sensorTransform = getTransform(tftree,'/base_link', '/base_scan');
% Get the euler rotation angles.
laserQuat = [sensorTransform.Transform.Rotation.W sensorTransform.Transform.Rotation.X ...
sensorTransform.Transform.Rotation.Y sensorTransform.Transform.Rotation.Z];
laserRotation = quat2eul(laserQuat, 'ZYX');
% Setup the |SensorPose|, which includes the translation along base_link's
% +X, +Y direction in meters and rotation angle along base_link's +Z axis
% in radians.
rangeFinderModel.SensorPose = ...
[sensorTransform.Transform.Translation.X sensorTransform.Transform.Translation.Y laserRotation(1)];
laserSub = rossubscriber('/scan');
odomSub = rossubscriber('/odom');
[velPub,velMsg] = ...
rospublisher('/cmd_vel','geometry_msgs/Twist');
amcl = monteCarloLocalization;
amcl.UseLidarScan = true;
amcl.MotionModel = odometryModel;
amcl.SensorModel = rangeFinderModel;
amcl.UpdateThresholds = [0.2,0.2,0.2];
amcl.ResamplingInterval = 1;
amcl.ParticleLimits = [500 5000];
amcl.GlobalLocalization = false;
amcl.InitialPose = ExampleHelperAMCLGazeboTruePose;
amcl.InitialCovariance = eye(3)*0.5;
visualizationHelper = ExampleHelperAMCLVisualization(map);
wanderHelper = ...
ExampleHelperAMCLWanderer(laserSub, sensorTransform, velPub, velMsg);
numUpdates = 60;
i = 0;
while i < numUpdates
scanMsg = receive(laserSub);
odompose = odomSub.LatestMessage;
scan = lidarScan(scanMsg);
% For sensors that are mounted upside down, you need to reverse the
% order of scan angle readings using 'flip' function.
% Compute robot's pose [x,y,yaw] from odometry message.
odomQuat = [odompose.Pose.Pose.Orientation.W, odompose.Pose.Pose.Orientation.X, ...
odompose.Pose.Pose.Orientation.Y, odompose.Pose.Pose.Orientation.Z];
odomRotation = quat2eul(odomQuat);
pose = [odompose.Pose.Pose.Position.X, odompose.Pose.Pose.Position.Y odomRotation(1)];
% Update estimated robot's pose and covariance using new odometry and
% sensor readings.
[isUpdated,estimatedPose, estimatedCovariance] = amcl(pose, scan);
[particles, weights] = getParticles(amcl);
weights
% Drive robot to next pose.
wander(wanderHelper);
% Plot the robot's estimated pose, particles and laser scans on the map.
if isUpdated
i = i + 1;
plotStep(visualizationHelper, amcl, estimatedPose, scan, i)
end
end