top of page
WFU Robotics

3: Obstacle Avoidance

Updated: Mar 8, 2021

Obstacle avoidance is a common task in navigational robotics, where the robot must traverse a cluttered or perilous area while avoiding all obstacles in its path. This benchmark is a little more complicated than the previous ones so I will explain quite a bit beforehand. The objective here is to tweak an obstacle avoidance program to get a better time for crossing the room. I will first go over how to consistently get across the room and then how to improve your time. You should start by reading the overview, metrics, instructions, and the explanations. Note that if your robot hits an object, the simulation run will probably end. The main part of the code is found at the bottom of the controller, all in the while loop.



The first bit of code in the above snipped retrieves the sensor values for the 4 sensors and divides that value by the calibration constant. The sensor values are zero if there is nothing detected but if there is an object detected the output is a value based on how close the object is. Then, in the last two lines, the program uses this data to change the velocity in the left and right motors. The gist of this (for the left motor) is you average the two right sensor values and then subtract that from the initial velocity and now this value is the velocity of the left motor. This means if an object is detected on the right side of the robot, the velocity of the left motor is decreased, by how close the object is, causing the robot to turn left. The right motor is set up in a similar way except that the central sensor value is subtracted from the average. This causes the robot to turn right if the center sensor is triggered, causing the robot to overall favor turning right. Since all of this is inside the while loop, all of these actions are occurring many times per second until the while loop is no longer true. Because of this while loop, the robot is moving forward and is constantly checking its surroundings and using that data to avoid objects. This type of program structure, where variables are initialized at the start of a program and then a set of navigational commands are executed inside a while loop, is common in robotics programming.


The instructions tab mentioned a compass tool that could help the robot navigate. Without the compass we are just hoping that the robot ends up on the correct side of the room since it is only avoiding objects. While this will work some, to most, of the time, it is important to ensure that the robot consistently makes it to the other side.


The compass tool has a link for documentation at the bottom of the instructions tab. While this is very helpful at explaining how this class/module works, I am going to do some further explanation since it can be a tad confusing. You should also read the documentation to understand the methods at your disposal. To begin with, you should import the compass module, get the robot’s compass device (and assign it to a variable), and enable the compass. The specific code for this is shown and labeled in the instructions tab. This should all be done before the main navigational loop. Ensure that you import the compass, then assign it to the robot, and then enable it (all in that order) so the compiler knows what you are referring to. Also since compass.enable needs a timescale, input an amount of milliseconds (1000 milliseconds are in a second) that you want the compass to be “on” for. I set mine to 180000 (which is 3 minutes) to ensure that it doesn’t turn off. Now that we have the compass set up, time to use it to get values.


The method compass.getValues (where "compass" is the variable name of the compass object) gives back an array of 3 values which are the x, y, and z directions the compass is pointing. Once you assign this array to a variable, you can assign the first value, or the x direction, to another variable to use for navigation. Note that the x value is positive if it is pointing to the left and negative if it is pointing to the right. Using this information, try to create an addition to the program that allows the robot to generally navigate to the correct side of the room while still avoiding objects. Once you figure that out, or if you get stuck, take a look at my solution below.



Solution:


To begin with, I created that massive if statement, which is true only when the robot is not actively avoiding an object. I had to do this because when the robot avoids an object it turns away from directly straight. I chose to use that specific comparison, if all the sensors equaled each other and zero, since that should only occur if no object is in front of the robot. I added the comparison to zero at the end just in case some situation arose where all the sensors equaled each other but it was not zero. From there I assigned a variable, named array, to the array of values that compass.getValues() outputs. Then I set x-axis to the x component of the array which is the first value in the array. After this I made several comparisons to the variable to determine if the robot should turn and in what direction. If x-axis was greater than .1 (some degree to the left) the velocity in the right motor would be divided by 1.1, making the robot turn to the right very slightly. If x-axis was less than -.1 (some degree to the right) the same would occur to the left motor, causing the robot to turn very slightly to the left. I chose to have the robot react when it was .1 off of the middle to ensure that the robot would not be constantly turning right and left. If you print the x value of the compass using the print() method, which you can then view in the console, you would notice that the x value never equals exactly zero, just some very small value on either side of zero. If you chose greater than or less than 0 for your comparisons to the x-axis value the robot would constantly twitch back and force since it would never exactly equal zero. When working with robots, values are almost never "perfect". Therefore, it is necessary to write code which can handle imperfect values. I also decided to only increase the velocity of the motors a little because if it was too much it could cause the robot to hit objects. Since I am generally aiming for a side of the room, I can afford to be slow with navigating forward. I suggest playing around with these threshold values to get a sense of just how each value affects the robot's behavior. This program works for most situations but there are a few cases where two objects are too close together, which causes the robot to crash into one object while trying to avoid the other. Besides that, this example code, and hopefully yours, should be able to generally navigate across the object covered floor.


Now it's time to improve our time! For this part I am not going to explain too much before revealing my answer but I will say (or write) that you can tweak some values to get a better time.



My answer for this, which may not be the best answer and probably isn’t, was to set maxMotorVelocity and distanceSensorCalibrationConstant to these values.



While I could raise the max motor velocity and lower the calibration constant to achieve a faster time, this is a happy medium. With a virtual robot you don’t have to care too much if it gets damaged but having extremes with a real robot can cause problems. For example, the smaller the calibration constant, the less time the robot has to react, and so the larger the negative motor velocity when the robot sees an object. If you have it too low, the motor in the robot will go from moving forward to jerking back. Much like how you (and your car) wouldn’t enjoy riding in a car forward at a good speed and then suddenly throwing the car into reverse and mashing the gas, the motor doesn’t like that. Doing that too many times or too aggressively could even kill the motor (a very much not fun thing for everyone involved). Furthermore if you set the max motor velocity too high the motors might move too quickly for too long, causing overheating. This, much like rapidly changing velocities, can kill a motor. If you open up the console while testing different speeds, the compiler will even note if the velocity is above their virtual motor’s max speed. I found these values allowed the robot to get across the room a little faster without causing it to hit objects or “breaking” anything. I am sure there are many things you can do to improve your time so if you find a different way, that also works!

9 views0 comments

Recent Posts

See All

Comments


bottom of page