Monday, 15 May 2017

Sprint 2 - Zhuo Fan Ye

In my previous sprint, it was written based on kick-starting the approaches to the project. Code was written in Python (with OpenCV) and C++ for the mbed side. Since then, tasks were split and the team started working on organised tasks. This is described in a very general one liner form; the specifics of the subtask within this task will be broken down further down


Task breakdown (general)

Zhuo Fan, Deepak:  Decode and split the string being sent down in a serial format to extract the F, x, y, and d parameters. Use the parameters to calibrate default servo positions control the mock-lamp according to the data received.

Terry:  Script the face detection program in Python and send F, x, y, and d down in the serial buffer in a string format to be decoded and extracted by us on the mbed side. Built a tiny mock-lamp for code testing purposes.


Introduction to the coding tasks for mbed in C++

When coding the mbed in C++, two things were kept in mind –
1)  The string is being sent down in this format “F01x000y000d000
2)  The individual variables – F, x, y, and d will be used to move 3 servo’s accordingly.

The variables:

F: Face, this exists because multiple faces could appear in front of the camera at once, and the lamp needs to make a decision on which face should it focus on
x: The degrees on the virtual x-axis that the lamp needs to pan
y: The degrees on the virtual y-axis that the lamp moves up and down based on it
z: An approximation of the distance between the user and the camera


The process:

Designing the program flow in C++ revolved around a simple structure. First, breakdown the string into the individual variables to be extracted. Then, with the extracted variables, move the servos with the degrees that were received in the variables. This whole process is done inside a while(1) loop that keeps the program constantly running.

The existence of the mini mock lamp built by Terry made things easier by allowing us to figure the proper offsets and default positions that each servos should be in. That resulted in the default position for the three servos to be x = 85, y=45, and d =85. As seen in the code below

servopan.write(85);     //initialise position
servotilt.write(45);    //initialise position
servotiltd.write(85);   //initialise position



Problems encountered:

The biggest problem that was present during the testing of the servo movements is that the movements seemed “jerkish”. The servos we were using to test the mock-lamp do not have the smooth transition in the movements. The same program was tested on better quality servos that can deal greater torque; apparently it fixed the jerk problem

Also, there existed synchronisation issues where the next string was sent in before the first string was being read. So to fix this, there needs to be a control element making sure that there is no synchronisation problems with the decoding of the string, making sure that the string is decoded before the next string kicks in. In that instance, an acknowledgement was used to make sure the contents are received before the next string in sent. This was dealt with after this sprint, before making it behave like a Real-Time Operating System.



The code:

#include "mbed.h"
#include "C12832.h"
#include
#include "Servo.h"

C12832 lcd(p5, p7, p6, p8, p11);
//SErvo 1 & 2
Servo servopan(p21);
Servo servotilt(p22);
Servo servotiltd(p23);
//Serial
Serial pc(USBTX, USBRX);
// Buffer
char *token;
char buffer[128];
int f,d,x,y,yt;

int main()
{  

servopan.write(85);     //initialise position
servotilt.write(45);    //initialise position
servotiltd.write(85);   //initialise position

pc.baud(9600);
lcd.cls();
while(1) {              

            pc.gets(buffer,17);

            lcd.locate(0,0);
            lcd.printf("%s\n", buffer);
            token = strtok(buffer, " '' TFxyd");
            T = atoi(token);
            token = strtok(NULL, " '' TFxyd");
            F = atoi(token);                    // Get face #
            token = strtok(NULL, " '' TFxyd");
            x = atoi(token);
            pc.printf("%d", x);                    // Det x pos
            token = strtok(NULL, "'' TFxyd");
            y = atoi(token);                    // Get y Pos
            token = strtok(NULL, "'' TFxyd");
            d = atoi(token);                    // Get D pos
            lcd.locate(0,21);
            //lcd.locate(0,17);
            yt = y;               // Set new vari for d outside sweetspot
            lcd.printf("y=%d x=%d D=%d",x, y,d);
//************************** Pan *************************           
            if (f == 1)                     // Only enter for face # 1
            {
                if((x+85)<10 180="" degree="" nbsp="" o:p="" prevent="" swing="" to="">
                    {
                        servopan.write(10); // Pan min
                    }
                    else if((x+85)>170)
                    {
                        servopan.write(170);    // pan max
                    }
                    else {
                    servopan.write(85+x);       // Else write to servo
                    }
        //****************************** End of pan *************************************
                    if((yt+45)<5 90="" degree="" nbsp="" o:p="" prevent="" swing="" to="">
                    {
                        yt = 10;
                    }
                    else if((yt+45)>90)
                    {
                        yt = 85;   //to prevent 180 degree swing
                    }
                    if((y+85)<5 180="" degree="" nbsp="" o:p="" prevent="" swing="" to="">
                    {
                        y = 10;
                    }
                    else if((y+85)>175)
                    {
                        y = 175;   //to prevent 180 degree swing
                    }
                   
                    if(d<120 close="" is="" nbsp="" o:p="" user="" when="">
                    {
                        servotilt.write(yt+45);
                        servotiltd.write(y+85);
                    }
                    else if(d>180)   //when user is far away
                    {
                        servotilt.write(yt+45);
                        servotiltd.write(y+85);
                    }
                    else  //when user is at comfort zone
                    {
                        servotilt.write(y+45);
                        servotiltd.write(85);
                       
                    }
            }
            wait(0.1);    // Delay of 10 ms
    }

}

No comments:

Post a Comment