Как постоянно обновлять окно перенасыщения? - PullRequest
10 голосов
/ 23 июля 2011

У меня есть настоящий робот, который заказывает моего виртуального робота в открытом гл.Я хочу показывать каждое движение моего главного робота (реального робота) в подчиненном (виртуальном в открытом gl) онлайн, поэтому мне нужно постоянно обновлять мое окно перенасыщения, фактически до тех пор, пока реальный робот перемещает моего виртуального, и вседвижение должно быть онлайн.

Я всегда получаю данные от мастера с помощью функции получения данных, но я не знаю, как мне обновить окно.

Вот мой код:

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

  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;

  }

Ответы [ 3 ]

9 голосов
/ 23 июля 2011

Вы можете вызвать glutPostRedisplay после обновления, которое планирует перерисовку окна (с использованием функции отображения GLUT, конечно), как только оно вернется в очередь сообщений, я думаю.

Но это не сработает, если вы непрерывно опрашиваете данные робота в бесконечном цикле, поскольку это постоянно блокирует программу. Вам следует использовать таймер для планирования обновления робота через короткие промежутки времени, чтобы между этими обновлениями программа могла вернуться в основной цикл событий и перерисовать окно. Или вы можете вызвать некоторую функцию, которая сообщает каркасу посетить цикл обработки событий. Ваш пример кода на самом деле не объясняет, как вы это делаете в данный момент (или я просто не знаком с вызываемыми вами функциями).

2 голосов
/ 23 июля 2011

GLUT предлагает вам обратный вызов в режиме ожидания (void (*)(void) подпись), установленный через glutIdleFunc. Получите входные данные робота в обработчике простоя. Или используйте отдельный поток опроса данных, заполняя структуры данных; используйте семафор для разблокировки в режиме ожидания после поступления новых данных, используйте блокировку с таймаутом, чтобы ваша программа оставалась интерактивной. Псевдокод:

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();
}
0 голосов
/ 25 июля 2011

Я бы сделал следующее. Обращайтесь с glutMainLoop() как с вашим циклом, и каждый раз, когда вы обрабатываете один getData(), который вы рисуете, он будет быстрее, чем вы думаете.

Чтобы получить «непрерывное» обновление, вам необходимо:

  1. Обработка данных (getData() затем ваши расчеты)
  2. Перерисовка (Display() перенасыщение вызывает это каждый раз, когда оно зацикливается)
  3. Другие функции, определенные с помощью glut_____Func()
  4. Вернуться к 1

Переполнение продолжается до завершения программы.

//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;
}
...