SLAM Simulation Part
SLAM Simulation Part
Understanding ROS
We read about ROS terminology and how it actually works, in general the
best picture to summarize what we need from ROS is:
Figure 1 Source:https://wiki.ros.org/rosbuild/ROS/Concepts#Stacks
rostopic info <topic name> —- the publishers and subscribers of the topic
<pub node> =
rospublisher("/chatter","std_msgs/String","DataFormat","struct")
send(<publisher> ,<message>)
Use [rossubscriber] to create a subscriber to any topic, rossubscriber detects
its message type automatically, so you do not need to specify it.
<sub node>=rossubscriber("/pose","DataFormat","struct")
save('posedata.mat','<recieve varaible>')
messageData = load('posedata.mat')
messageData.<receive variable>
delete('posedata.mat')
Callbacks
Instead of using [receive] to get data, you can specify a function to be called
when a new message is received (Callbacks). Callbacks are essential if you
want to use multiple subscribers.
robotpose =
rossubscriber("/pose",@exampleHelperROSPoseCallback,"DataFormat","struc
t")
One way of sharing data between your main workspace and the callback
function is to use global variables.
The TurtleBot uses the /odom topic to publish its current position and
orientation (collectively denoted as pose). Since the TurtleBot is not equipped
with a GPS system, the pose will be relative to the pose that the robot had
when it was first turned on.
This matrix can be plotted as the image below, where the center is always
the robot (wherever it moves) and the x positive axis is on the left:
Based on the distance readings from the laser scan, we can implement a
simple obstacle avoidance algorithm. we can use a simple while loop to
implement this behavior.
Firstly, we set some parameters that will be used in the processing loop. we
can modify these values for different behavior.
Run a loop to move the robot forward and compute the closest obstacles to
the robot. When an obstacle is within the limits of the distanceThreshold, the
robot turns. This loop stops after 20 seconds of run time.
tic;
scan = receive(laser);
rosPlot(scan);
data = rosReadCartesian(scan);
x = data(:,1);
y = data(:,2);
minDist = min(dist);
velmsg.Angular.Z = spinVelocity;
velmsg.Linear.X = backwardVelocity;
else
velmsg.Linear.X = forwardVelocity;
velmsg.Angular.Z = 0;
end
send(robot,velmsg);
end
Some observations:
When you make the robot rotate and move in the same time, it will
move in a circle around a fixed point, the radius of this circle increase
by increasing the linear velocity and decrease when increasing the
Angular velocity.
Gazebo Simulation simulates momentum (when you give it high speed
and then send a stop signal it doesn’t stop right away, rather it slides)
The above algorithm doesn’t take into account if the min(dist) is in
which direction relative to the robot (in front of him, in his way of
movement…etc), so sometimes it senses an object next to him and
acts as if it will rush into it while that’s not true, rather, sometimes the
robot makes it worse and get more close to that object!
For the sake of this last observation, I modified the algorithm to take
into account the place of this min(dist) point:
x = data(:,1);
y = data(:,2);
% Compute distance of the closest obstacle
dist = sqrt(x.^2 + y.^2);
[minDist,minDistIndx] = min(dist);
% Command robot action
if minDist < distanceThreshold && y(minDistIndx)>0 &&
y(minDistIndx)<3*x(minDistIndx)
% If close to obstacle on the left or front, back up slightly and
spin clockwise
velmsg.Angular.Z = -spinVelocity;
velmsg.Linear.X = backwardVelocity;
disp("left");
disp ("y=");
disp (y(minDistIndx));
disp ("x=");
disp (x(minDistIndx));
send(robot,velmsg);
pause (revtime);
elseif minDist < distanceThreshold && y(minDistIndx)<0 &&
y(minDistIndx)>-3*x(minDistIndx)
% If close to obstacle on the right, back up slightly and spin
counterclockwise
velmsg.Angular.Z = spinVelocity;
velmsg.Linear.X = backwardVelocity;
disp("right");
disp ("y=");
disp (y(minDistIndx));
disp ("x=");
disp (x(minDistIndx));
send(robot,velmsg);
pause (revtime);
else
% Contuine on forward path
velmsg.Linear.X = forwardVelocity;
velmsg.Angular.Z = 0;
send(robot,velmsg);
end
%send(robot,velmsg);
%disp(minDist);
End
load officemap.mat
show(map)
Did a loop that Receive laser scan and odometry message, then Create
lidarScan object to pass to the AMCL object. For sensors that are mounted
upside down, you need to reverse the order of scan angle readings using
'flip' function. Then, compute robot's pose [x,y,yaw] from odometry
message. Then, update estimated robot's pose and covariance using new
odometry and sensor readings. Finally, Drive the robot to next pose and plot
the robot’s estimated pose, particle, and laser scans on the map.
After first AMCL update, particles are uniformly distributed inside the free
office space:
After 8 updates, the particles start converging to areas with higher likelihood:
After 60 updates, all particles should converge to the correct robot pose and
the laser scans should closely align with the map outlines.
.
We loaded a Lidar data and used (lidarSlam) class. The SLAM algorithm takes
in lidar scans and attaches them to a node in an underlying pose graph. The
algorithm then correlates the scans using scan matching. It also searches for
loop closures, where scans overlap previously mapped regions, and
optimizes the node poses in the pose graph.
We use (addscan) to add scans one by one in a loop into the lidarSlam class.
We identified Loop Closure Threshold to 205, and studied the effect of Loop
Closure Search Radius.
Figure 2 Studying the LCR effect.