Virtual Driving Environment Construction (4)

Hits: 0

Long Yunyao’s personal blog, please indicate the source for reprinting.

Personal blog address: http://yaoyl.cn/huan-jing-da-jian-si-2/

Improvements to obstacle movement

In the previous version. Our obstacle movement and scene movement are placed in the same for loop. Although the operation of the code is reduced, boundary problems are prone to occur. Obstacles or obstacles often appear during program operation. In order to fix this bug, I will rewrite this part of the code in case the convenience disappears suddenly before reaching the car.

demand analysis

Most of the results of brainless writing code are constant bugs, and the previous text is forgotten after writing. In order to improve the clarity and accuracy of the code, Ting Zhe helps us to clarify our thinking, let’s first organize our code by writing pseudo-code. What are the requirements of the program, and a rough implementation method.

need

Obstacles can appear from the building on the left, and after reaching the middle of the road, they will stay for a short time (waiting for a car to hit).

By decomposing and analyzing this process, we can roughly get the following process:

  • Timing when obstacles appear: There is an obstacle on the left & it has been more than 10s since the last time it disappeared
  • Obstacle stop timing: It has reached the middle of the road, and the stop time has not reached 2s
  • Obstacle disappears verse timing: After staying for 2s, the obstacle disappears

The pseudo-code

  • First judge whether the obstacle has disappeared, then judge whether there is an obstacle on the left side, and then check whether the disappearance time has reached 10s, if the condition is met, update the appear flag and let the obstacle start to move
  • Start stepping on the obstacle until it reaches the boundary, then update the appear_tmp, update the appear flag, and record the current time
  • If the current state is static and the dwell time has not reached 2s, keep pos unchanged
  • Otherwise, if the stay time exceeds 2s, update the appear to disappear to make the obstacle disappear. At the same time, use appear_tmp to record the disappearing time, which is convenient for judging the appearance time of the obstacle.

Code

// First get the building situation on the left 
    int left_temp = building_left_flag;
     // bdw_appear has 3 values, 0 means it has disappeared, 1 means it is moving, 2 means moving to the border, and it has been stationary 
    if (bdw_appear == 0 ) {
         if ( left_temp >> 11 & 0b1 == 1 ) {
            time(&appear);
            // If it has been 5s since the last appearance, update the record and update the flag at the same time 
            if (appear - appear_tmp >= 5 ){
                appear_tmp = appear;
                bdw_appear = 1;
            }
        }
    }else if(bdw_appear == 1){
        glBindTexture(GL_TEXTURE_2D, texture[4]);
        glLoadIdentity();
        glTranslatef(child_run_len, -1.0f, -7.0f);
        glCallList(children);
        if (child_run_len >= -0.5 ) {
             //child_run_len = -3.0f; 
            //bdw_appear = false; 
            // just moved to the border 
            if (bdw_appear == 1 ){
                time(&appear_tmp);
                child_pos = -7.0f;
                bdw_appear = 2;
            }
            child_run_len = -0.5f;
        } else {
             // The speed of the child is constant 
            child_run_len += 0.1f ;
        }
    }else{
        time(&appear);
        // If it has been 5s since the last appearance, update the record and update the flag at the same time 
        if (appear - appear_tmp >= 2 ){
            appear_tmp = appear;
            child_run_len = -3.0f;
            bdw_appear = 0;
        }else{
            glBindTexture(GL_TEXTURE_2D, texture[4]);
            glLoadIdentity();
            // The pos of the obstacle should also be added with run_len, so that the obstacle can move with the surrounding objects after reaching the center of the road and move together to produce a feeling of approaching people 
            glTranslatef(child_run_len, -1.0f , child_pos+run_len);
            glCallList(children);
        }
    }

Realize that obstacles appear randomly from both sides

In order to be more similar to real driving, we should not make the obstacle appear only from one side, but make it possible to appear on both sides. Therefore, we need to make further changes on the original code.

demand analysis

need

First of all, we temporarily let the tumbler appear in two cases, in the first case, it appears from the left, and in the second case, it appears randomly from both sides. The mode conversion is controlled by pressing the key ‘c’ (change the value of appear_mode).

Therefore, when we press the ‘c’ key, we need to switch the mode. Next, in DrawGLScene, a series of operations will be performed according to the value of appear_mode. If appear_mode is the default 0, let the obstacle appear from the left, if If the appear_mode is 1, the obstacle will appear from both sides.

If the obstacle appears from both sides, every time the obstacle is about to appear , we need to use a flag to save whether the obstacle appears from the left or the right. When drawing the obstacle, we will pass This flag is used to determine how the object is moving.

  • When the obstacle appears: The obstacle itself has disappeared, and it has been more than 10s since the last disappearance. It is determined which side it will appear from, and there is a building on that side
  • The timing of the obstacle’s movement: it has already appeared, according to the flag that has been obtained in the previous step to determine whether to go left or right, until it reaches the critical point
  • When the obstacle is stationary: it has reached the middle of the road, and the stay time has not exceeded 2s
  • When the obstacle disappears: It has been stationary for more than 2s

The pseudo-code

  • First, we need to add the control event of the key ‘c’ in the KeyPressed function, and modify the appear_mode.
  • Next, in DrawGLScene, we will judge the appear_mode. If the appear_mode is 0, execute the previous code. If the appear_mode is 1, enter the event on both sides.
  • When appear_mode is 1, if the current state is disappearing, if the current state has disappeared for more than 10s, then randomly decide where the obstacle should appear, and then check whether there is a building on this side, if there is a building, save the ruling position (left or right), while updating the current state to move
  • When the appear_mode is 1, the current state is moving, according to the ruling, if the ruling decides to come out from the left, the starting point is set to the left, and at the same time, the child_run_len is continuously increased until it reaches the boundary; if the ruling decides to come out from the right, the starting point is Set to the 1.0f position and keep decreasing until it stops at the -0.5f position.
  • When stopping, set the appear_mode to 2, record the start time, and disappear after staying in place for two seconds.

Code

int left_temp = building_left_flag;
    int right_temp = building_right_flag;
    if (appear_mode == 0 ) {
         // bdw_appear has 3 values, 0 means it has disappeared, 1 means it is moving, 2 means it is moving to the boundary, and has been stationary
         if (bdw_appear == 0 ) {
             if (left_temp >> 11 & 0b1 == 1 ) {
                time(&appear);
                // If it has been 5 s since the last appearance , update the record and update the flag at the same time
                 if (appear - appear_tmp >= 5 ) {
                    appear_tmp = appear;
                    bdw_appear = 1;
                    child_run_len = -3.0f;
                }
            }
        } else if(bdw_appear == 1) {
            glBindTexture(GL_TEXTURE_2D, texture[4]);
            glLoadIdentity();
            glTranslatef(child_run_len, -1.0f, -7.0f);
            glCallList(children);
            if (child_run_len >= - 0 . 5 ) {
                 //child _run_len = - 3.0 f;
                 //bdw _appear = false ;
                 // just moved to the border
                 if (bdw_appear == 1 ) {
                    time(&appear_tmp);
                    child_pos = -7.0f;
                    bdw_appear = 2;
                }
                child_run_len = -0.5f;
            } else {
                 // The speed of the child is constant
                child_run_len += 0.1f;
            }
        } else {
            time(&appear);
            // If it has been 5 s since the last appearance , update the record and update the flag at the same time
             if (appear - appear_tmp >= 2 ) {
                appear_tmp = appear;
                child_run_len = -3.0f;
                bdw_appear = 0;
            } else {
                glBindTexture(GL_TEXTURE_2D, texture[4]);
                glLoadIdentity();
                glTranslatef(child_run_len, -1.0f, child_pos+run_len);
                glCallList(children);
            }
        }
    }else if(appear_mode == 1) {
        if(bdw_appear == 0) {
            time(&appear);
            if (appear - appear_tmp >= 5 ){
                 // odd numbers are left, even numbers are right
                 if (rand() & 0b1 == 1 ) {
                     if (left_temp >> 11 & 0b1 == 1 ) {
                        time(&appear);
                        appear_tmp = appear;
                        bdw_appear = 1;
                        left_or_right_flag = 1;
                        child_run_len = -3.0f;
                    }
                }else{
                    if(right_temp >> 11 & 0b1 == 1) {
                        time(&appear);
                        appear_tmp = appear;
                        bdw_appear = 1;
                        left_or_right_flag = 0;
                        child_run_len = 1.0f;
                    }
                }
            }
        } else if(bdw_appear == 1) {
            if(left_or_right_flag == 1){
                glBindTexture(GL_TEXTURE_2D, texture[4]);
                glLoadIdentity();
                glTranslatef(child_run_len, -1.0f, -7.0f);
                glCallList(children);
                if (child_run_len >= - 0 . 5 ) {
                     //child _run_len = - 3.0 f;
                     //bdw _appear = false ;
                     // just moved to the border
                     if (bdw_appear == 1 ) {
                        time(&appear_tmp);
                        child_pos = -7.0f;
                        bdw_appear = 2;
                    }
                    child_run_len = -0.5f;
                } else {
                     // The speed of the child is constant
                    child_run_len += 0.1f;
                }
            }else{
                glBindTexture(GL_TEXTURE_2D, texture[4]);
                glLoadIdentity();
                glTranslatef(child_run_len, -1.0f, -7.0f);
                glCallList(children);
                if(child_run_len <= -0.5f) {
                    if(bdw_appear == 1) {
                        time(&appear_tmp);
                        child_pos = -7.0f;
                        bdw_appear = 2;
                    }
                } else {
                    child_run_len -= 0.1f;
                }
            }
        } else {
            time(&appear);
            // If it has been 5 s since the last appearance , update the record and update the flag at the same time
             if (appear - appear_tmp >= 2 ) {
                appear_tmp = appear;
                child_run_len = -3.0f;
                bdw_appear = 0;
            } else {
                glBindTexture(GL_TEXTURE_2D, texture[4]);
                glLoadIdentity();
                glTranslatef(child_run_len, -1.0f, child_pos+run_len);
                glCallList(children);
            }
        }
    }

You may also like...

Leave a Reply

Your email address will not be published.