User:Medelen8/ENES100/Weekly Update Example

Project Preference
Not applicable. As part of a summer project (faculty development grant), I proposed to build and test a self-balancing LEGO robot to become more familiar with LEGO Mindstorms and the built-in support from MATLAB and Simulink.

Problem Statement
There are two goals of this project:
 * build a two-wheeled "Segway" robot, from an existing design, using LEGO Mindstorms components
 * use built-in MATLAB (or Simulink) functionality to develop a control algorithm that allows the robot to self-balance (remain upright autonomously) while stationary

Project Plan
Note: This project actually took place over the course of about 10 weeks, but only 30-40 were spent on the project (comparable to a ENES100 project cycle). For the purposes of this example documentation, the work is represented as taking place over four weeks. The plan for this project is as follows:
 * Week 1: Review online documentation of self-balancing LEGO robot and built-in support from MATLAB/Simulink. Order any parts not present in Engineering Lab inventory.
 * Week 2: Assemble the robot. Learn how to use Simulink to create block diagram models for LEGO NXT.
 * Week 3: Test basic functionality of assembled robot. Test communication between MATLAB and NXT (controller), using a very simple program.
 * Week 4: Test an existing self-balancing algorithm on the physical robot to verify self-balancing behavior. Troubleshoot when it doesn't work.

Week 1 Narrative
NOTE TO STUDENTS: This example does not do the following, but you are responsible for doing this: ''Link to any CDIO documents you are working on. Compare your task (from CDIO discuss page) with what you actually did.''

During this week, I wanted to collect existing documentation for a self-balancing LEGO robot that I had seen online. I plan to use a pre-designed robot, and start my testing with a pre-designed control algorithm that has been tested. I downloaded the Self-Balancing Two-Wheel Robot package from the Mathworks "File Exchange". Mathworks is the company behind MATLAB and Simulink, which recently included built-in support for robotics platforms like LEGO NXT and Arduino. I reviewed the documentation in the package, which includes the following: Based on the assembly instructions, I determined all of the LEGO parts required to build one robot. The robot is fairly small (height = 10 in) and simple (less than 100 pieces), so I concluded that a basic LEGO Mindstorms kit would include the basic elements needed. Instead of using parts from the Engineering Lab, I decided to buy a new educational kit to supplement our inventory. Existing parts would have been sufficient, except for the special items noted below. I placed an order, through the college, to purchase the following parts: The Gyro Sensor is needed to sense rotational acceleration of the robot, which is required for autonomous correction of tipping. The Bluetooth dongle enables wireless communication between the computer (running MATLAB/Simulnk) and the NXT (robot controller). The DC charger is used to recharge the battery pack for the NXT, although it can also be power using AA batteries. I expect that the parts will arrive in approximately one week.
 * the mechanical design of the robot, with assembly instructions
 * tutorials (.html files) for getting the system working
 * multiple Simulink models (.mdl files)
 * supporting MATLAB code (.m files)

Week 2 Narrative
The parts ordered in week 1 arrived on schedule. Using the parts from the kit, and the gyro sensor, I assembled the robot using the assembly instructions (lego_selfbalance_building_instructions.pdf) included in the downloaded package (see week 1). The assembly process was quite simple, taking only about 30 minutes to complete. The robot consists of two large drive wheels, two motors (Ports B and C, one driving each wheel), an ultrasonic distance sensor (Port 2), a gyro sensor (Port 4), the NXT controller, and an assortment of standard LEGO pieces. The gyro sensor is mounted in an orientation that allows it to sense angular accelerations of the robot when tipping about its axles.

After assembling the robot, I shifted focus onto the programming environment. I had only used Simulink once or twice, and to a very limited extent, so I spent a couple of hours becoming familiar with creating and running basic Simulink models from standard blocks. Next, I installed the "Target for Use with LEGO MINDSTORMS NXT Hardware" Simulink library, which includes blocks specifically created for use with LEGO robots. For example, there are blocks called "Gyro Sensor", "Motor", and "Ultrasonic Sensor". The installation is simple: just type "targetinstaller" at the MATLAB command prompt. A window appears that lets you select from a list of supported hardware; in this case, LEGO MINDSTORMS NXT. Once the library was installed, I verified that I could view the LEGO-specific Simulink blocks and include them in Simulink models. This worked on the first try, so everything is ready for testing the robot in week 3.

Week 3 Narrative
After two weeks of preparation work, I was finally ready to test the robot! First, I wanted to make sure that the ultrasonic sensor was working properly, and try to understand the numerical values provided by the sensor to the NXT. Using the NXT display to display the sensor reading, I confirmed that the sensor was working properly. Next, I needed to verify basic communication between MATLAB/Simulink and the NXT (controller). Instead of starting with wireless Bluetooth communication, I decided to first use the more reliable wired USB connection. In order to test communication, I built a very simple Simulink model, using a Switch, two Constants, and blocks from the Lego library installed last week. The algorithm powers both motors at a constant speed (50), but only when the input from the ultrasonic sensor is greater than or equal to 20 cm. From within Simulink, I selected "Tools-->Run on Target Hardware-->Run" to run this algorithm on the NXT. Unfortunately, this did not work and I received an error message. Before running, I had to select "Tools-->Run on Target Hardware-->Options" and set the Target Hardware to "LEGO MINDSTORMS NXT". After that change, the "Run" command worked. The NXT screen indicated that the program was running, but neither motor was turning, regardless of the distance between my hand and the ultrasonic sensor. Then I realized that the ports were set incorrectly in my Simulink model. In the Ultrasonic Sensor block, I needed to change the Port setting from Port 1 to Port 2. On the second attempt, I ran the model and it worked (see video)! When the desk is close to the sensor, the motors stop turning. This algorithm was actually running on the NXT, not on the computer. I verified this by unplugging the USB cable and running the program directly from the NXT (using the orange and gray buttons).

Having confirmed operation with a simple model, it was time to try the self-balancing algorithm provided in the package described in Week 1. I opened the model named lego_selfbalance.mdl and clicked through all of the blocks, trying to understand how the control algorithm works. This model was significantly more complicated than the one I created. By double-clicking on each block, I explored the internal logic within the block. I gained a basic understanding of the control algorithm, but without grasping all of the details. I selected "Run on Target" and tried to run the algorithm on the robot, using the USB connection. To my amazement, it actually worked "as advertised". As shown in the video, the robot remains upright, even when perturbed. Next week, I plan to try making the robot move while it remains balanced. I also plan to try using a wireless connection, instead of USB.

Week 4 Narrative
Compared to my original plan (see above), I am ahead of schedule. Progress has been unexpectedly smooth through the first three weeks, giving me plenty of time to explore the capabilities and limitations of this robot's design (hardware and software).

First, I wanted to make the robot move (forward, backward, and turning) while remaining upright. In the Simulink model (lego_selfbalance.mdl), this was accomplished by changing the "Speed" and "Turn Angle" constant inputs. For an easy test, I modified "Speed" to 10 and ran the program, being sure to unplug the USB cable from the NXT as soon as the program was finished downloading. When I heard the beeping noise, indicating that the robot was calibrating, I knew it was safe to unplug the USB cable. I quickly discovered that a speed of 10 is too fast for my small office. I changed the speed to 5 and re-tested. At this speed, the robot moved forward while remaining upright. Unfortunately, there is no logic telling the robot to stop or not run into things. Next, I tried making the robot rotate in place (speed=0,turn angle=10), which was successful.

After several iterations of changing constants, downloading the program, unplugging the USB cable, observing the robot's behavior, turning off the NXT, plugging in the USB cable, and turning it the NXT back on, I was ready to try wireless communication. After some difficulties with setting up the Bluetooth adapter, I was able to establish a wireless connection between the computer and NXT. Using this wireless connection, programs can be run in "External" mode. This is set up by clicking "Tools-->Run on Target Hardware-->Options" and checking "Enable External Mode". In external mode, variables can be dynamically changed while the program is running on the robot. For example, the robot's forward speed can be adjusted DURING operation. This is very helpful for trial-and-error when fine-tuning algorithm parameters. Unfortunately, even with a Bluetooth connection, when the Simulink model needs to be modified and re-downloaded to the NXT, this must be done using the USB cable. Apparently it can't be done wirelessly.

After a couple hours of testing, I became frustrated by a significant limitation of the existing algorithm: there is no obstacle-avoidance behavior. The robot will run into a wall and fall over. In fact, the ultrasonic sensor is not even used. I spent several hours developing two different modified algorithms to address this problem. The first algorithm (shown below) switches between forward (speed=2) and reverse (speed=-2), depending on the input from the ultrasonic sensor. When the sensor reading falls below 20 cm, meaning that the robot is near an obstacle, the speed switches from 2 (forward) to -2 (reverse). As shown in the video below, this algorithm works, but it has significant drawbacks. Most notably, the robot oscillates back and forth around the specified distance from an obstacle. Also, the robot does not react well when the obstacle is moving. The robot tends to lose balance and fall over if the speed constants are set much higher than +/- 2. Ultimately, it is a solution that is too simple. The second attempt at obstacle-avoidance is based on using a look-up table to continuously vary the speed, based on the sensor reading. After many failed attempts at this, and much use of the "Scope" block for debugging, I finally figured out how to use the "1D Lookup Table" block. The final model is shown below. This algorithm, while not perfect, is certainly an improvement over the first attempt. This allows the robot to avoid running into obstacles, even when the obstacles are moving (like people). When showing this to my children, I realized that this robot follows you around; it is a great toy for robotics demonstrations. Note that MANY iterations were required in order to fine-tune the 1D Lookup Table, such that output speeds were matched to corresponding input sensor readings in a way that produced the desired behavior (not running into things). If the speed changes (accelerations) are too large, then balancing cannot be maintained and the robot will fall over.

NOTE TO STUDENTS: This example does not do the following, but you are responsible for doing this: ''Link to any CDIO documents you are working on. Compare your task (from CDIO discuss page) with what you actually did.''