Skip to the content.

Lab 10

Open-Loop Square

What is the duration of a velocity command?

As the code shows below the duration of a velocity command is 4 seconds for both the translational and rotational velocity commands.

Does the robot always execute the exact same shape?

A close look at the true ground truth of the robot (the green plot in the video below) over time seems to suggest that it consistently executes the same shape. Over many many runs a visible difference might occur. Additionally if you sped the robot up and reduce the asynio sleep times drastically, then I think that you would begin to see it not follow the same path every time. This is because the simulation seems to be running on a different process than the Python script. When the Python script sleeps, it may not sleep for exactly the same amount of time every time a sleep is called especially if this sleep is a much smaller number. Thus the Python script may set the velocity in the simulation at irregular times causing the shape the robot follows to vary slightly from time to time.


while cmdr.sim_is_running() and cmdr.plotter_is_running():
    pose, gt_pose = cmdr.get_pose()
    cmdr.plot_odom(pose[0], pose[1])
    cmdr.plot_gt(gt_pose[0], gt_pose[1])
    while True:
        cmdr.set_vel(.1,0)
        
        await asyncio.sleep(4);
        pose, gt_pose = cmdr.get_pose()
        cmdr.plot_odom(pose[0], pose[1])
        cmdr.plot_gt(gt_pose[0], gt_pose[1]) 
        cmdr.set_vel(0,math.pi/8)
        
        await asyncio.sleep(4);
        pose, gt_pose = cmdr.get_pose()
        cmdr.plot_odom(pose[0], pose[1])
        cmdr.plot_gt(gt_pose[0], gt_pose[1])
        cmdr.set_vel(.1,0)
        
        await asyncio.sleep(4);
        pose, gt_pose = cmdr.get_pose()
        cmdr.plot_odom(pose[0], pose[1])
        cmdr.plot_gt(gt_pose[0], gt_pose[1])
        cmdr.set_vel(0,math.pi/8)
        
        await asyncio.sleep(4);
        pose, gt_pose = cmdr.get_pose()
        cmdr.plot_odom(pose[0], pose[1])
        cmdr.plot_gt(gt_pose[0], gt_pose[1])
        cmdr.set_vel(.1,0)
        
        await asyncio.sleep(4);
        pose, gt_pose = cmdr.get_pose()
        cmdr.plot_odom(pose[0], pose[1])
        cmdr.plot_gt(gt_pose[0], gt_pose[1])
        cmdr.set_vel(0,math.pi/8)
        
        await asyncio.sleep(4);
        pose, gt_pose = cmdr.get_pose()
        cmdr.plot_odom(pose[0], pose[1])
        cmdr.plot_gt(gt_pose[0], gt_pose[1])


Obstacle Avoidance

My virtual object avoidance robot is shown in a video below.


The heart of the code I used to accomplish this is below.

while True:
      cmdr.set_vel(.1,0)
      while True:
          if cmdr.get_sensor()[0]>.3:
              cmdr.set_vel(.1,0)
          else:
              cmdr.set_vel(0,math.pi/8)
              await asyncio.sleep(4)
          pose, gt_pose = cmdr.get_pose()
          
          await asyncio.sleep(.001)


By how much should the virtual robot turn when it is close to an obstacle?
I found that the obstacle avoidance works well when you instruct the robot to rotate in 90 degree intervals. I found that if I told it to rotate in really small intervals, it would often collide with the wall because it would turn until the TOF beam went past and edge and would drive forward. Becuase the TOF beam does not account in anyway for the width of the robot, the side of the robot, would then clip the corner.

At what linear speed should the virtual robot move to minimize/prevent collisions? Can you make it go faster?
I made the robot go fairly slow at a speed of only .1m/s. This seemed to work very well from the standpoint of avoiding collisions. I was able to make the robot go much faster. I increaesd the rate at which it turned and decreased the duration of the turn by the inverse of the increase. I also made the robot go much faster translationally and increased the distance from the wall at which it turned by about a factor of 3. This is shown in the video below. In the simulation this was easy, but because of the dynamics of the robot, in real life speeding up obstacle avoidance would be much more challenging.



How close can the virtual robot get to an obstacle without colliding?
It is not always apparent that the robot has run into the wall so this is hard to do visually. In order to figure this problem out, I wrote the following python code which produced the result shown in the image.


I ran the simulator and recorded sensor measurements as the robot sat still over 15 seconds. I found that the standard deviation of the sensor measurements is about .034 meters. In order to rarely crash into the wall, it would be a good idea to stay 3 standard deviations away from the wall or .102 meters away. If you do this, then you can be pretty sure you will not crash into the wall and if you want to be even more sure, you can start to turn away from the wall at an even farther distance away. This does not necessarily account for the width of the car which you may need to take into account when turning so you do no clip the side of the robot on the wall. Additionally, I am assuming that the standard deviation of the sensor values are about the same at any distance in the simulator. In the real robot, it might be the case that the standard deviation of the sensor is greater at greater distances.

Does your obstacle avoidance code always work? If not, what can you do to minimize crashes or (may be) prevent them completely?
The obstacle avoidance code seems to be pretty reliable when I simulate it. However, it does seem to eventually settle into a repeating pattern that does aviod obstacles but is less interesting. To avoid entering into this repeating pattern, I could add some randomness into the amount that it turns when it gets to a wall. I think that the 90 degree turns work well for maps with right edges. It could be the case that it there were smooth edges, then the robot would rotate past exits out of whatever crevise it was trapped in and would get stuck. Additionally, if your robot is crashing in the simulator it may be a sign you are getting too close to the wall and sensor noise is affecting you more and thus you can tell your robot to start turning farther back.