Brandon Collier 20111101 ECE478 Homework 1 Description: Using existing algorithms, the goal was to document how genetic algorithms work and then adapt their examples to produce code suitable for the KHR-1 robot. For this assignment I elected to evaluate Padmashri Gargesa’s algorithm and produce an updated algorithm that evaluates fitness more quickly. The KHR-1 robot is currently suffering from a balance problem. Every time the robot is issued a walk command, it falls over or otherwise walks unstably. The idea was to use the aforementioned algorithm to calculate optimal center of gravities for various positions of the KHR-1 in order to overcome this issue. Initial Analysis: First, in order to start the project I needed to evaluate how genetic algorithms worked. Using the documentation, provided code and Embedded Robotics by Thomas Braunl, I worked through to understand the genetic algorithm I would be working with. The next step was to get the code to compile because the code given in the documentation was incorrect and would not compile as given. The first modification was to reduce the memory footprint. All the numbers were cast as double floating point, the largest declaration C++ would allow. Next was to run statistical analysis on the code using Microsoft Visual Studio to figure out where the code spent the majority of the processing time. Finally, we could then start to adapt the code plus optimizations in order to simulate and find optimal center of gravities for the KHR-1 in various positions. Results: Because of the tolerances of the servos of the KHR-1, we were only realistically concerned with one significant figure right of the decimal, so the first improvement was to cast all the variables to a type that is more manageable, thus floating point was chosen as it is only 4 bytes large compared to double floating point which is by comparison doubly large. For example, line 16 contains the code segment: double maximum_fitness=0.0, average_fitness=0.0, minimum_fitness=0.0, sum_fitness=0.0; This segment is computationally intensive for all the fitness calculations, as none of them are native, single clock cycle instructions and thus it was changed to: float maximum_fitness=0.0, average_fitness=0.0, minimum_fitness=0.0, sum_fitness=0.0; Next, many of the random numbers were being cast as double floating point to represent integer values, thus unnecessary use of bytes to represent unused numbers. All such were changed to either integer or floating point as usage deemed necessary. These changes resulted in a memory footprint of the code about 25KB smaller, from 344KB to 329KB, but only marginally increased execution speed per generation dropping access to the output (per every 10,000 generations) from 23 seconds to 22 seconds. A significant enough improvement, though, when the generations increase to over 1,000,000 between solutions. The next potential improvement was seen when the code was the use of the random number generator, where the code spent the majority of the time just computing random numbers. Since each chromosome had a maximum length of 30, assuming each member of the population got all 30 chromosomes, that is 4,500 random numbers per generation. Now, take that calculation across 10,000 generations between fitness algorithm updates, which is 45,000,000 random numbers which proved to be the largest bottleneck of the program because the processor now has to wait on the pseudo random number generator to return each value. Including an exclusive or shift random number generator (example below), the code was able to produce random numbers much more quickly. The issue with the xor shift method then became uniformity. Some runs would enter loops because the random numbers were too evenly distributed within the population thus calling for the need to use a combination of the xor shift method to speed calculation and calling C++’s random function to ensure no pattern behavior emerged. XOR Shift Random Number Generator Example: static unsigned long x=123456789, y=362436069, z=521288629; //faster random number generator unsigned long xorshiftrand(void) { unsigned long t; x ^= x << 16; x ^= x >> 5; x ^= x << 1; t = x; x = y; y = z; z = t ^ x ^ y; return z; } Now that the code is optimized to run more quickly, work began to port it over to report the center of gravity of the KHR-1. In order to report values more easily, the center of gravity would be split up between 3 orientations of the robot as follows: left-right, forward-backward, top-bottom. These values would be read back to the user upon finding the optimal value for a given position. The fitness function is based upon the current center of gravity with respect to the KHR-1 in the home position. Here is a 3D representation of the KHR-1 on a checkerboard plane. The red ball represents the center of gravity and the green cylindrical pyramid represents the x-y center of gravity only. Center of gravity shift raising only left arm. Extreme center of gravity example, the robot would fall over. Conclusion Optimization was key for the initial genetic algorithm and after implementing the xor shift pseudo randomness, runtime was cut down to seconds to find complex solutions assuming no loops were created by impossible conditions to optimize. Further, memory management is key in order to ensure programs run optimally, despite systems having massively more memory today, writing programs that can exist entirely in cache is important to reducing stalls caused by fetching information off-die. Both of these optimizations will allow for genetic searches of semi-optimal solutions nearly in real time and may allow the code to be run on the fly in order to assist the robot with complex movements. Unfortunately, the whole scope of the assignment remains unfinished. Due to time constraints imposed by other classes the algorithm was unable to be fully ported to model the KHR-1’s center of gravity. Other technical difficulties arose with the discovery that one of the robots had the battery pack installed while the other did not. The inclusion of the battery shifted the center of gravity less with arm and leg movements but having both robots would necessitate two different versions of the program in order to model them accurately. The next hurdle came into modeling the robots’ movements in 3d space as both simulators used would allow movements that were not physically allowed by the robot. This issue still remains unresolved as the movement is complex enough to model without the inclusion of limits on the robot’s range of movement. The description of the problem and modeling may go beyond the practical application of knowing the fitness of each position in relation to its center of gravity.