Professional Documents
Culture Documents
MECH 472
Report Project
Presented to
Brandon Gordon
Concordia University
Figure 1: CAD of the required design to achieve the competition
We initially had a design that was on “two floors” laser cut with plexiglass, but the target
could not fit at the required height to let the other team reach it. Therefore, we changed to the
design in figure 1 with minor changed we 3D printed our frame that could fit everything on one-
level.
Figure 2: Process Map of the Robot with yellow as the starting point
After a brief summary of how’d we programed our robot let’s take a detailed look the
sequence of our programing method.
First we want our robot to align with the target, our program always starts with align with
the target, we used the equation had been given in the sample programing, e = r – theta, e is the
error that we are using to turn our robot, r is the target angle and theta is the robot angle. The two
circles forms the theta angle represents the colors on the robot, and circle that is further away
represent the target color. But the problem is that it is not working for scenario 3 and 4 refers to
figure 3.
For the scenario 3 our robot angle theta is greater than 90 degrees and less than 180 degrees,
our target angle is less than -90 degrees and greater than -180 degrees. In this case our error
equation becomes
𝑒 = (180 − 𝑡ℎ𝑒𝑡𝑎) − (−180 − 𝑟) = 360 + (𝑟 − 𝑡ℎ𝑒𝑡𝑎) = 3.14159 + (𝑟 − 𝑡ℎ𝑒𝑡𝑎) 𝑖𝑛 𝑟𝑎𝑑𝑖𝑎𝑛𝑠
For the scenario 4 our robot angle theta is less than -90 degrees and greater than -180 degrees, our
target angle is greater than 90 degrees and less than 180 degrees. In this case or error equation
becomes
𝑒 = (−180 − 𝑡ℎ𝑒𝑡𝑎) − (180 − 𝑟) = −360 + (𝑟 − 𝑡ℎ𝑒𝑡𝑎)
= −3.14159 + (𝑟 − 𝑡ℎ𝑒𝑡𝑎) 𝑖𝑛 𝑟𝑎𝑑𝑖𝑎𝑛𝑠
Apply those equation in our program our robot has been able to align with the target in all the
directions, once the align problem has been solved then we can move on to the obstacle avoiding
method.
OBSTACLE DETECTION
In order to avoid obstacle we decided as a team to check the perpendicular distance of the
line connecting the robot (Rxy) and the target (Txy) with the Radius (Oxy) of the obstacle. So we
derived the equation of the line from robot to target as below;
2
𝐿𝑖𝑛𝑒 𝑜𝑓 𝑅𝑜𝑏𝑜𝑡 𝑡𝑜 𝑇𝑎𝑟𝑔𝑒𝑡 (𝑅𝑥𝑦 , 𝑇𝑥𝑦 ) = √(𝑇𝑦 + 𝑅𝑦 ) + (𝑇𝑥 + 𝑅𝑥 )2
From the line connecting the robot and target, the equation of the perpendicular distance
is described below;
If this perpendicular distance from obstacle is greater that the radius of the obstacle, then
it means that there is no obstacle between the robot and target. In other words if this
perpendicular distance is less than the radius of obstacle, then it means that there is an obstacle
between the robot and target as seen in the figures below.
If there was no obstacle between the robot and the target the robot would turn on the laser
and then move forward. The purpose of moving forward was to make sure we would get closer to
the target each time in case it changed direction we would have been closer therefore we would
have been able to adjust faster to the new position of the target. At first, we had issue to move
forward with a smooth motion, the robot was moving toward the target with saccade movement.
We programmed for 3 obstacles and for 2 targets with the same color, but with the approach
we used we could not find an “easy” way to program is.
First for the 3 obstacles, we had the perpendicular distance of the 3 obstacles from the line
linking the robot and the target. If that perpendicular distance was shorter than the radius of the
obstacle that meant there was an obstacle in the way. But then, our robot had to turn 30 degrees
and move forward which was not a good sequence for this. The geometry of 3 obstacles on the
board was way more complex and hardly suitable to the programing we had been working with.
We wanted to use the appropriate angle, but as we encountered issues doing an exact angle (which
was replaced by fixed 30 degrees) we could not get a specific angle for this purpose as well.
Second for the 2 targets, we were taking both centroid and finding the one that belonged to us by
analyzing the distance from one color of our robot. This part was working fine with the assumption
that because we were playing laser tag the other team would not try to come to close to our robot
which would have confused our target determination.
Once there is an obstacle in between our robot and the target, our robot can identify the
obstacle right away, sometimes it turns really well but some time it turns very slowly.
// initialize pointers
ibyte *pa, *p_rgb0;
i2byte *pl;
int i = 0;
char ch;
double th, th_obstacle, e, ed, ei, dt, dx_robot, dy_robot, dy_target, dx_target,
dy_obstacle, dx_obstacle, kp, ki, kd, u; //counter;
double r, rd, ep, r_temp;
unsigned char uR, uL, uLas; // one byte value for servo angle (0-255)
unsigned int count1;
int count2;
static int count3;
double count4;
unsigned char count5;
Sleep(100);
int number_of_labels;
double r_obstacle = 0;
double ic_DB = 0;
double jc_DB = 0;
double ic_R = 0;
double jc_R = 0;
double ic_PK = 0;
double jc_PK = 0;
double ic_G = 0;
double jc_G = 0;
double ic_P = 0;
double jc_P = 0;
double ic_LB = 0;
double jc_LB = 0;
double ic_DO = 0;
double jc_DO = 0;
p_rgb0 = rgb0.pdata;
pl = (i2byte *)label.pdata;
pa = a.pdata;
// number of pixels
width = rgb0.width;
height = rgb0.height;
// initialize variables
ei = 0.0; // integral of the error
dt = 0.1; // estimate of the sampling rate
ep = 0.0; // error for previous sample
while (1)
{
while (1)
{
find_object(nlabel, number_of_labels);
//Robot Back
position_Dark_Blue_Object(rgb0, a, label, number_of_labels, ic_DB,
jc_DB);
view_image(rgb0);
t = high_resolution_time() - t0;
th = atan2(dy_robot, dx_robot);
r = atan2(dy_target, dx_target);
printf("\n1st align");
rd = 0.0;
ed = (e - ep) / dt;
ep = e;
ei += e*dt;
//uR >= 91.5 && uR <= 92.5 && uL >= 91.5 && uL <= 92.5
if (uR == 92 && uL == 92)
{
uR = 92.0;
uL = 92.0;
uLas = 65.0;
break;
}// end if (Ur==92...)
find_object(nlabel, number_of_labels);
view_image(rgb0);
find_object(nlabel, number_of_labels);
view_image(rgb0);
t = high_resolution_time() - t0;
th = atan2(dy_robot, dx_robot); // use atan2 to get the
correct quadrant
r = atan2(dy_target, dx_target);
th_obstacle = atan2(dy_obstacle, dx_obstacle);
{
r = 0.61087 + th_initial;
}
else if (th_obstacle > 1.570796 && th_obstacle < 3.14159 && r > 1.570796 && r < 3.14159)
{
r = -0.61087 + th_initial;
}
else if (th_obstacle < 0 && th_obstacle > -1.570796 && r < 0 && r > -1.570796)
{
r = -0.61087 + th_initial;
}
else if (th_obstacle < -1.570796 && th_obstacle > -3.14159 && r < -1.570796 && r > -
3.14159)
{
r = 0.61087 + th_initial;
}
rd = 0.0;
ed = (e - ep) / dt;
ep = e;
ei += e*dt;
uR = 92 + 90 * u;
uL = 92 + 90 * u;
uLas = 65;
//printf("\n\nuR = %lf, uL = %lf", (float)uR, (float)uL);
find_object(nlabel, number_of_labels);
view_image(rgb0);
while (1)
{
find_object(nlabel, number_of_labels);
position_Dark_Blue_Object(rgb0, a, label, number_of_labels, ic_DB, jc_DB);
view_image(rgb0);
e = abs(distance_to_travel - distance_travelled);
uR = 180;
uL = 4;
uLas = 65;
printf("\nTravelling!");
printf("\n\nuR=%lf,uL=%lf", (float)uR,
(float)uL);
while (1)
{
find_object(nlabel, number_of_labels);
t = high_resolution_time() - t0;
th = atan2(dy_robot, dx_robot);
r = atan2(dy_target, dx_target);
rd = 0.0;
ed = (e - ep) / dt;
ep = e;
ei += e*dt;
uR = 92 + 90 * u;
uL = 92 + 90 * u;
uLas = 65;
uR = 92.0 ;
uL = 92.0 ;
uLas = 65;
break;
}//end if (UR==92...)
}// end while for align object
//break;
} // end if(abs(e)<1)
}//end if
find_object(nlabel, number_of_labels);
view_image(rgb0);
t = high_resolution_time() - t0;
r = atan2(dy_target, dx_target);
//printf("\n\nt = %lf, r(deg) = %lf", t, r / 3.14159 * 180);
printf("\nalign 1st else if");
rd = 0.0;
ed = (e - ep) / dt;
ep = e;
ei += e*dt;
uR = 92 + 90 * u;
uL = 92 + 90 * u;
uLas = 65;
view_image(rgb0);
t = high_resolution_time() - t0;
r = atan2(dy_target, dx_target);
//printf("\n\nt = %lf, r(deg) = %lf", t, r / 3.14159 * 180);
printf("\nAbs error else if ");
rd = 0.0;
//break;
}// end of while abs(e<=0.2)
find_object(nlabel, number_of_labels);
//robot tracker
position_Red_Object(rgb0, a, label, number_of_labels, ic_R, jc_R);
position_Pink_Object(rgb0, a, label, number_of_labels, ic_PK, jc_PK);
dist_DB_to_obstacle = sqrt(ic_DB_to_obstacle*ic_DB_to_obstacle +
jc_DB_to_obstacle*jc_DB_to_obstacle);
}//end of while(1)
close_serial(h1);
return 0;