14

I have a real robot that is ordering my virtual robot in open gl. I want show every movement of my master robot(real robot) in slave (virtual one in open gl) online, so i need to update my glut window continuously, actually as long as real robot moves my virtual one moves too, and all these movement should be online.

I get data from master always with get data function, but I dont know how I should update the window.

Here is my code:

********************************************/

  void OnIdle(void){  
    initSocket();

  printf("\n  Defining Step Time Parameters and Initial Conditions for solving Dynamic equations\n");

  xi=0;
  xf=0.1;
  printf("\n    end value x         : %f ",xf); 
  i=0;  yi[i]=0; 
  i++;yi[i]=-1.570796;
  i++;yi[i]=-1.570796;
  i++;yi[i]=0;
  i++;yi[i]=0;
  i++;yi[i]=0;
  ndata=2; fi=1;

  double counter=0.1;

  Eqdifp(v1,v2,v3,v4,v5,v6,xi,xf,yi,ndata,p,fi);


  for(int i=0;i<50;i++)
    //while(1)
  {

      getData();

      printf("\n");
      for(int i=0;i<6; i++)
      {

          printf("%d = %.3f\n", i,drecvbuf[i]);
      }
      printf("\n");

   yi[0]=v1[ndata];
   yi[1]=v2[ndata];
   yi[2]=v3[ndata];
   yi[3]=v4[ndata];
   yi[4]=v5[ndata];
   yi[5]=v6[ndata];
    printf("my nadata %f\n",v1[ndata]);
    counter=counter+0.1;

    Eqdifp(v1,v2,v3,v4,v5,v6,xi,xf,yi,ndata,p,fi);
    glutPostRedisplay();
 }
  }
/////////////////////////////////////////////////////
  int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
    glutInitWindowSize(900,500);
    int u=glutCreateWindow("3DOF robot");
    myinit();
    createMenu();
    glutIdleFunc (OnIdle);
    glutDisplayFunc(Display);
    glutReshapeFunc(reshape);
    glutKeyboardFunc(KeyDown);

    glutMainLoop(); 

    System::Timers::Timer^ aTimer = gcnew System::Timers::Timer( 100 );

      // Hook up the Elapsed event for the timer.
    aTimer->Elapsed += gcnew System::Timers::ElapsedEventHandler( OnTimedEvent );

      // Set the Interval to 2 seconds (2000 milliseconds).
    aTimer->Enabled = true;
    return 0;

  }
Likak
  • 373
  • 1
  • 5
  • 19

3 Answers3

15

You can call glutPostRedisplay after the update, which schedules the window to be redrawn (using GLUT's display func, of course) as soon as it returns to the message queue, I think.

But this won't work if you are continously polling the robot data in an infinite loop as this continously blocks the program. What you should do is use a timer to schedule the robot update in short intervals, so that between these updates the program can return to the main event loop and redraw the window. Or you can call some function, which tells the framework to visit the event loop. Your code sample doesn't really explain how you do it at the moment (or I'm just not familiar with the functions you call).

Christian Rau
  • 45,360
  • 10
  • 108
  • 185
  • dear Christin,tnx for your answer – Likak Jul 24 '11 at 04:47
  • actually im new with open gl and even c++, not so professional. – Likak Jul 24 '11 at 04:48
  • so , i'd prefer using opengl's function , something like that one you told(glutPostRedisplay), but i dont know how. i need something not so complex! – Likak Jul 24 '11 at 04:51
  • i edited the up codes and this is the suggested way i tried but it didnt work, i got confused:(( – Likak Jul 24 '11 at 07:21
  • @bahare By the way, `glutPostRedisplay` does NOT belong to OpenGL, but to GLUT. OpenGL is an interface for programming the graphics hardware (displaying things), whereas GLUT is a GUI abstraction library to make the creation of simple OpenGL programs easier. But OpenGL doesn't have anything to do with such tasks as GUI or event handling. – Christian Rau Jul 28 '11 at 12:56
4

GLUT offers you a idle callback (void (*)(void) signature), set through glutIdleFunc. Retrieve the robot input data in the idle handler. Or use a separate thread polling the data, filling data structures; use a semaphore to unlock idle after new data arrived, use a locking with timeout so that your program remains interactive. Pseudocode:

Semaphore robot_data_semaphore;

void wait_for_data(void)
{
    SemaphoreLockStatus lock_status = 
        semaphore_raise_timeout(robot_data_semaphore, RobotDataTimeout);
    if( lock_status == SEMAPHORE_RAISED ) {
        update_scene_with_robot_data();
        semaphore_lower(robot_data_semaphore);
        glutPostRedisplay();
    }
}

void main(int argc, char *argv[])
{
/* ... */
    semaphore_init(robot_data_semaphore);
    Thread thread_robot_data_poller = thread_create(robot_data_poller);
    glutIdleFunc(wait_for_data);

/* ... */
    thread_start(thread_robot_data_poller);
    glutMainLoop();
}
datenwolf
  • 159,371
  • 13
  • 185
  • 298
  • i tried what you said, but it didnt work, i changed the up codes, and used your way, could you take a look, and say whats with that?tnx alot:) – Likak Jul 24 '11 at 07:26
  • 1
    @bahare: The idle handler must return withing about 50ms to keep the program responsive. Also the display update will not happen until the idle handler returned. glutPostRedisplay just sets some flag. In the idle handler you should so what you'd place in the default branch of an event processing loop – without the loop. – datenwolf Jul 24 '11 at 09:46
  • would you correct the up codes in a way you say! I tried alot of ways but it doesnt work. – Likak Jul 24 '11 at 14:43
  • @bahare: For this I'd require the full source code, since the part you posted does not contain suffcient information. – datenwolf Jul 25 '11 at 08:41
0

I would do the following. Treat glutMainLoop() as your loop and every time you process one getData() you draw it, it will be faster than you think.

What needs to happen for you to get a 'continuous' update is to:

  1. Process data (getData() then your calculations)
  2. Redraw (Display() glut calls this every time it loops)
  3. Other functions defined using glut_____Func()
  4. Back to 1

Glut keeps going until the program is exited.

//called every time glutMainLoop
//do data processing
void OnIdle(void)
{  
    getData();

    printf("\n");
    for(int i=0;i<6; i++)
    {
        printf("%d = %.3f\n", i,drecvbuf[i]);
    }
    printf("\n");

    yi[0]=v1[ndata];
    yi[1]=v2[ndata];
    yi[2]=v3[ndata];
    yi[3]=v4[ndata];
    yi[4]=v5[ndata];
    yi[5]=v6[ndata];
    printf("my nadata %f\n",v1[ndata]);

    Eqdifp(v1,v2,v3,v4,v5,v6,xi,xf,yi,ndata,p,fi);
}
//also called every loop of glutMainLoop
void Display()
{
    ...
    //Your previous Display() function just add this:
    glutPostRedisplay(); //everytime you are done 
                        // drawing you put it on the screen
}

int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
    glutInitWindowSize(900,500);
    int u=glutCreateWindow("3DOF robot");
    myinit();
    createMenu();
    glutIdleFunc (OnIdle);
    glutDisplayFunc(Display);
    glutReshapeFunc(reshape);
    glutKeyboardFunc(KeyDown);

    ///////////////
    // SETUP YOUR INITIAL DATA
    System::Timers::Timer^ aTimer = gcnew System::Timers::Timer( 100 );

    // Hook up the Elapsed event for the timer.
    aTimer->Elapsed += gcnew System::Timers::ElapsedEventHandler( OnTimedEvent );

    // Set the Interval to 2 seconds (2000 milliseconds).
    aTimer->Enabled = true;

    initSocket();

    printf("\n  Defining Step Time Parameters and Initial Conditions for solving Dynamic equations\n");

    xi=0;
    xf=0.1;
    printf("\n    end value x         : %f ",xf); 
    i=0;  yi[i]=0; 
    i++;yi[i]=-1.570796;
    i++;yi[i]=-1.570796;
    i++;yi[i]=0;
    i++;yi[i]=0;
    i++;yi[i]=0;
    ndata=2; fi=1;

    Eqdifp(v1,v2,v3,v4,v5,v6,xi,xf,yi,ndata,p,fi);
    //////////////

    //Start the Main Loop
    glutMainLoop(); //This statement blocks, meaning that until you exit the 
                    // glut main loop no statments past this point will be executed.


    return 0;
}
Gideon W
  • 11
  • 2