An autonomous robot for warehouse pick-up and delivery

As online shopping continues to grow rapidly, warehouses face increasing demands for order fulfillment. The deployment of autonomous robots allows warehouses, like those in Amazon, to scale their operations more effectively. By automating the process of picking and transporting items, robots can navigate the warehouse environment swiftly, minimizing the time required to fulfill orders. They can follow optimized routes, avoiding congestion and taking advantage of the shortest paths, resulting in faster order processing and improved overall productivity.

The goal of this project is to design a robot that can localize itself within a known maze, navigate while avoiding obstacles, detect and load a block from a predefined loading zone, and deliver the block to its potential drop-off locations.

Project Requirements

The purpose of this project is to design and build a rover that is able to localize itself within a maze when placed in a random location, move through the maze without hitting any obstacles, find and pick up find a 2” x 2” x 2” block (<0.5lb), and drop it at one of the four predetermined locations. The rover will demonstrate an audible indication when it arrives at the loading zone and delivers the load.

There will be limitations on the mechanical and electrical aspects of the design such as:

  • Robot size should be smaller than 12” x 12” x 12” and lighter than 5 lbs

  • Maximum budget of $300

  • It must be battery powered

  • It must use no touch sensors

The Design

The design is inclusive of mechanical, electrical, and control system design stages.

  1. In the mechanical design stage, the focus was on the chassis design, drive system, and pick-up/drop-off mechanism.

  2. In the electrical design stage, the focus was on the sensor locations and the system's electric circuit design with power distribution.

  3. In the control system design stage, the focus was on obstacle avoidance detection, localization & navigation strategy, and delivery strategy.

1. MECHANICAL DESIGN STAGE:

(i) Chassis Design

The design is split into 3 main layers to simplify the mechanical and electrical assembly process where each layer can be individually completed before being combined to form the final robot. Each layer is enclosed with removable walls to protect the electronics and contain the wires, while still allowing full access to the components for troubleshooting. All mounts, walls, and spacers within the chassis will be made from 3D printing using PLA. The plates that make up each layer will be laser cut from a single piece of 24” x 18” baltic birch plywood with a thickness of ⅛”, being cheaper and faster due to its 2D profile. 

The first layer contains the main drive system components: the servo motors, wheels, block holding ramp, the ultrasonic sensor to detect the block, and the battery.

The second layer houses all the electrical components that will be utilized for the drive system and pickup mechanism, and a Bluetooth module for communication.

The final layer houses the remaining ultrasonic sensors, compass, and Bluetooth module that will all be utilized for navigation and localization. A buzzer is added to this layer as well to produce an audible signal when reaching the loading zone, detecting the load, and delivering it. 

An additional goal for the design was to have easy access to both the mid and top-level Arduinos so that programming changes can be done without any disassembly required within the enclosed form. Thus both Arduino's ports are exposed at the edge of their respective layers. The battery must also be easily accessible due to the need to charge or replace it. The magnetic back plate and battery casing are designed to be quickly removed, without the need to disconnect any fasteners.

Battery and Arduino External Access

Robot with enclosure plates removed

Robot with enclosure plates and Battery and Arduino External Access

(ii) Drive System

The goal of the drive system is to maximize maneuverability while reducing system complexity. The system is composed of 2 NEMA 17 2A Stepper Motors, 1 on each side of the robot, horizontally aligned on the bottom layer. Paired with each motor are 2 L298N motor drivers situated on the second layer for bi-directional movement. The motors are positioned towards the center of the robot and a free-rotating follower wheel is added at the back for balance support. Stepper motors allow for precise positioning, while enabling 360 degrees in place by spinning the wheels in opposite directions. The added positioning capabilities offered by this design will significantly increase maneuverability in tight spaces, and the time needed to navigate through the maze.

Drive System Components and Layout

(iii) Pick-up/Drop-off Mechanism

The pickup system utilizes a 3D-printed collector arm paired with a single 35 kg-cm servo motor and an ultrasonic sensor for block detection. During pickup, the robot will position itself such that the back piece (Block Remover) is aligned around the block at a 90-degree angle from the ground. Once the block is detected by the ultrasonic sensor at the appropriate distance, the pickup system will be activated. The rectangular arm will swing downwards, sweeping the block up onto an inclined ramp within the robot. For block delivery, the system will conduct the same operations in reverse. The rectangular piece will swing upward (90 degrees) and the back piece (Block Remover) will guide the block down the ramp and out of the robot. The purpose of the ramp is to allow gravity to assist in removing the block. The benefit of this design is that it eliminates the need for a second motor to accomplish a gripping and lifting motion.

Step by Step Method of Pick Up and Drop Off Mechanism

2. ELECTRICAL DESIGN STAGE:

(i) Sensor Location

The navigation and localization of the rover will be accomplished by utilizing 7 sensors. The sensor locations and the coordinates of sensor locations are shown below. The x and y distances are from the center of the rover while the z distance is from the bottom plate. The rotation angle is positive counterclockwise.

Sensors U1 to U5 will be used for rover navigation through the maze, U3-U6 for localization, and U7 for block detection. When the rover arrives at the loading zone, the pick-up mechanism will be lowered down exposing U7 which will look for the block. Sensors for navigation and localization are mounted around 165 mm from the ground since the only limitation is the wall height of 305 mm, which is higher than the robot height of around 200 mm. The sensor U7 is mounted on the base plate that is around 15 mm above the ground since the limitation is the block height of 50 mm. Moreover, the angles of the sensors are chosen to optimize the area covered: front, corners, sides, and back.

All of the sensors are ultrasonic for several reasons:

  • Insensitiveness to light and dust

  • More reliable data

  • Wider operating range

(ii) System's Electric Circuit Design with Power Distribution

There will be a 12V battery pack used that essentially powers the design. The positive terminal of the battery is connected to two L298N stepper motor drivers and the negative terminal of the battery with the ground of the motor drivers. The reason why these two stepper motor drivers were used is firstly because two stepper motors were needed and only one motor driver can control one stepper motor maximum, and secondly each of the motor drivers can power an Arduino each and since two Arduinos were needed, two stepper motor drivers were utilized. 

Thus, the usage of 2 stepper motor drivers enables not only the control of the stepper motors for the drive system but at the same time powers the Arduinos themselves, hence reducing the need for any additional DC-DC converter for powering the Arduino.

Now, proceeding to the two Arduinos themselves. They will be referred to as Arduino Board 1 (left on diagram) and Arduino Board 2 (right on diagram).

The Arduino Board 1 is responsible for the following:

  1. Powering one 35 kg cm Servo Motor used for the block pick-up system 

  2. Controlling one Buzzer for block detection with a resistor in series 

  3. Powering one HC-05 Bluetooth module for serial communication 

  4. Controlling two NEMA 17 Stepper Motors [Note: It was ensured that the ENA and ENB pins on each stepper motor driver was connected to PWM digital pins on Arduino.]

The Arduino Board 2 is responsible for the following:

  1. Powering seven HC-SR04 ultrasonic sensors 

  2. Powering one HC-05 Bluetooth module for serial communication 

  3. Powering one HMC5883L digital compass for localization 

  4. Powering one humidity sensor AHT20 for aiding in accurate ultrasonic sensor readings

3. CONTROL SYSTEM DESIGN STAGE

(i) Obstacle Avoidance Detection

The first iteration for obstacle avoidance was determined through the use of the Matlab simulator with sensor positions as follows:

Initial Sensor Positions

Within the simulator, the robot successfully navigated the maze without hitting any obstacles. However, when the same model was implemented into the rover a major issue was found being faulty sensor readings. The simulator could not account for bad sensor readings when at an angle respective to the wall. As it would approach a wall on an angle the sensor values would read much larger distance values and thus not trigger the turning algorithm until a collision occurred.

Another problem with this method was that the rover would simply turn if it got too close to a wall without an indication of how straight it was driving. This resulted in a zig-zag patterned movement as it navigated through the maze, which caused major problems when trying to map the maze for localization as sensor readings was unreliable. 

During the second iteration for obstacle avoidance, the first challenge to overcome was to ensure that the robot remained parallel to the left or right wall at all possible instances. To do this, the two sensors on the left and right sides were turned to a 90-degree angle instead of the original 45 degrees, as shown below. A parallel function was then written that would rotate the robot until the difference between the two sensor values reached an experimentally tested tolerance as shown below as well.

Updated Sensor Positions

Cell Value Legend

Parallel Function Logic

Parallel left and right functions were set up so that the robot would maintain necessary orientation to the wall that is present on either side. Once the robot position is corrected, the side sensor readings would be accurate enough to determine its respective distance from the wall. A centering function was thus implemented that would rotate the robot away from the wall if it is in close proximity, move forward, and recall the parallel functions. The robot would repeat this process until it was within a certain threshold from the wall, shown below. The combination of these two functions allowed the robot to remain centered and straight as it navigated through the maze.

Centering Function Logic

The centering and parallel functions would continuously run, allowing the robot to move forwards while both conditions hold, until the front ultrasonic sensor detects a wall ahead. The robot would then turn 90 degrees in the direction of the largest side sensor reading. This same function was used to make 180 degree turns at dead ends by running the function twice as the front ultrasonic would still detect a wall after the initial turn. 

Another challenge experienced with the obstacle avoidance was that occasionally sensor values would trip, reading extremely high or low, even after each sensor was given its own trigger pin to avoid overlapped readings. To solve this, median filtering was added to the algorithm, finding the median of 4 sensor values. Although sensor values became much more reliable, it significantly slowed down the processing time. This issue was amplified by the fact that the motors were connected to a separate arduino, adding an additional delay by the time direction values were sent down from the main (sensor) arduino. The team tried having the robot move in discrete steps; but more success was achieved with continuous movement at a slower speed. 

The last major issue was to orient the robot after it was initially placed in the maze at a large angle. The parallel functions rely on the sum of the side sensors’ readings being less than 25 cm to ensure a wall is present; at extreme angles the sensors would read values far greater. Thus, an initialization code was written that would run once at the start to turn the robot regardless of the sum until the parallel criteria was met.

(ii) Location & Navigation Strategy

The initial plan for localization was to assign a value to each cell based on where an upwards-facing rover would detect the walls, as shown in Figure 2.2.1. In this method, the location of the walls around the rover would be identified using 4 ultrasonic sensors at angles 0, 90, 180, and 270, respectively. Next, based on the orientation of the rover in the real-world frame measured by a compass, the readings would be adjusted with an algorithm to convert the readings for an upwards facing rover orientation. For example, if the rover detected two walls on its side, but the orientation of the rover was turned 90 degrees clockwise, the readings of the walls would be adjusted (90 degrees counterclockwise in this example) to determine that an upwards facing rover would detect the walls on its front and back. Therefore, based on the legend shown below, a value of 5 would be assigned to this cell. This method would have created various unique patterns within the maze. By comparing the patterns read by the rover to the values of the maze shown below, localization would have been accomplished via two cell movements.

Localization Map with Cell Values

To implement this localization strategy, the use of a compass was needed to determine the orientation of the rover. However, the magnetic field created by all of the rover’s electronics interfered with the readings of the compass sensor. Hence, we had to change our localization strategy. The values assigned to each cell were changed to be based on the number of walls detected around the rover and their positions relative to each other, as shown below.

Updated Localization Map with New Cell Values

With this system, there were two strategies that could have been implemented for localization, Histogram analysis and Hard Coding patterns within the maze. Histogram analysis is the more robust method; however, it added more complexity to the project. The team decided to use the Hard Coding strategy for localization as it didn’t require the use of bluetooth, the strategy was less complex, and the team was short on time. 

In the Hardcoding strategy, the rover reads the number of walls on each cell it drives over, looks for three unique patterns on the maze, and localizes once it finds out one of the patterns. The first pattern is the “E” cell ([6,2]) as shown in Figure 2.2.3. Cell [6,2] is the only cell within the maze that has a value of E (no walls surrounding the cell). Once the rover reads a value of “E” it localizes at cell [6,2]. The second scenario is the reading pattern [D,B,C,B]. This pattern can be found in the cell when the robot passes the [3,4] [2,4] [1,4] [1,3] cells. Once the rover reads the aforementioned pattern it localizes at cell [1,3]. The final scenario is experienced when the rover passes cell [8,4] [8,3] [8,2] to read the pattern [A,B,D]. Once the rover reads this unique pattern it localizes at cell [8,2]. In all of these scenarios, the buzzer would go off for 2 seconds after localizing. 

Overall, this method worked very well for the first scenario (“E” cell), and not as well for the other two cases. The last two cases required reading a pattern of values in a row; however, sometimes the rover would read the value of a cell twice or it would read the wrong value. This made the second and third localization scenarios less reliable than the first. As a result, the team focused on locating the cell E from 4 different directions: approaching from [5,2], [6,1], [7,2], or [6,3].

The initial plan for navigation and path-finding was by using Breadth First Search algorithm (BFS). Using the BFS, the shortest path from the source cell to all the cells within the maze would be calculated and stored within a dictionary. By calling the destination cell from the dictionary, the path from the source cell to the destination cell would be given to the rover.

As we didn’t want to use bluetooth in our design to reduce complexity, the BFS pathfinding algorithm was coded in C++. However, when the code was transferred from C++ IDE to the Arduino IDE, it was noticed that the Arduino IDE did not have the required libraries (i.e. vector, queue) to implement the BFS pathfinding algorithm. Therefore, the team decided to hardcode the path finding. 

One of the main obstacles that we faced was determining the orientation of the rover when it localized at cell “E”. To resolve this issue, we used the front, sides and the back sensor readings to determine the distance from the wall. The pseudo code below shows how the orientation of the rover at cell “E” was determined. For the other two localization scenarios, the orientation of the rover is known as the rover needs to follow a specific path to localize. 

//after localizing at cell “E”

If sum(left_sensor, right_sensor) > 50

     If (front_sensor < back_sensor)

// robot facing up, turn 90 degrees CCW

     Else if (back_sensor < front_sensor)

          // robot facing down, turn 90 degrees CW

If sum(front_sensor, back_sensor) > 50

     If (left_sensor < right_sensor)

          // robot facing right, turn 180 degrees

     Else if (right_sensor < left_sensor)

          // robot facing left, keep going straight

To get to the loading zone after the rover is localized and its orientation is known, it rotates towards the loading zone (facing cell [5,2] - shortest path to the loading zone), and the rover runs the navigation functions (parallel and center functions mentioned before) until it sees two corners in a row (cell “C” in a row) and then reads the cell value “B”. At this point, it would know that it has reached cell [3,1] and stop, ringing the buzzer. 

(iii) Delivery Strategy

Upon arrival at the loading zone, the robot executes its block search strategy. To simplify the search process for these locations, the robot will scan 3 different rows within the loading zone to account for the 5 potential block locations, as shown in Figure 2.3.1. During the inspection process, the robot reads the difference between the top front sensor and the bottom gate sensor. If there is a considerable difference between the two values, the robot has successfully detected the block. 

Possible Block Locations for Pick Up

Starting at the entrance to the loading zone, the robot first inspects directly ahead. If no block is detected, the robot moves 6 inches to the first row which has been defined as the middle of the first square. To scan the row the robot rotates 90 degrees. If no block is detected the robot rotates 90 degrees back in the opposite direction and repeats the row search process for the remaining 2 rows. Once a block is detected, the robot will move forward until the appropriate block range conditions are met. Prior to making contact, the robot opens the gate with a 5 inch distance clearance to ensure the block does not interfere with the opening of the gate. Once the gate is open, the robot moves forward 5 inches and closes the gate to secure the block.

After picking up the block in the loading zone, the rover rotates 180˚ and begins moving. The obstacle avoidance code would return the rover to the “E” cell, at which point the hard coded path to the predetermined drop off zone is given to the rover. After the rover reaches the drop off zone the gate opens up and the block is dropped off. Finally, the rover backs up, closes its gate, runs the buzzer, and the task is completed.

Integration

When the robot is randomly positioned in the maze, the initialization function runs first to rotate the robot until it is straight with respect to the walls. After this, the obstacle avoidance algorithm will run continuously, navigating the robot and mapping the surrounding maze until one of the localization cases is met. 

Once the robot localizes and reaches cell E, it rotates accordingly to face towards the loading zone. After repositioning to take the shortest path, obstacle avoidance kicks back in, directing the robot towards the loading zone. The robot continues to move, counting two C and two B cells. Once the second B cell is found, the robot will move forward until sensing that it is no longer in between two walls (the sum of the two side sensors being greater than 25 cm). This provides a repeatable position for the block-pick up algorithm to begin. 

As the block-pick up code runs, two key functions from obstacle avoidance - parallel and centering - are used to ensure that the robot does not collide with the walls as it searches the area. The robot scans each tile and moves in discrete steps tracking its position and checking to ensure that the robot is parallel at an adequate distance from the walls with each movement. 

After finding and picking up the block, depending on which cell the robot has found the object at, the robot turns accordingly to end up in the direction necessary to take the shortest path back to cell E. The obstacle avoidance algorithm runs until the desired destination has been reached. 

To drop off the block, all possible drop off locations are hard-coded with a variable at the top of the code that can be initialized prior to beginning the trial to determine which destination to go to. Depending on the drop off location, specific cell patterns are programmed that tell the robot which direction it needs to go, and when it has reached its given destination. Obstacle avoidance algorithm runs with forced turns, depending on the drop-off location, until the final location has been found. Once the robot has arrived, a drop off function is run, reversing the robot slightly backwards, opening the gate to release the block, and finally closing the gate. 

It is important to note that continuous localization is not used, meaning that the robot does not know its exact location at all times. The robot rather determines its position in the maze at key checkpoints between objectives; initial localization cell, the loading zone, pick-up location, cell E before drop-off, and the final drop off position. In between these cases, the obstacle avoidance algorithm is run until the robot is able to find the next desired location in the sequence. This method greatly reduces the complexity of the code while still being able to achieve all objectives without the use of localization algorithms in Matlab.

Results

You can see it for yourself in the video below how in 2 mins 44 seconds we achieve the entire process. You can be the judge of the design which met all the constraints.

Previous
Previous

cnc kit

Next
Next

spy drone