Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Как постоянно обновлять окно перенасыщения?

Автор вопроса: LikakОтветов: 3

У меня есть настоящий робот, который заказывает моего виртуального робота в open gl. Я хочу показать каждое движение моего главного робота (настоящего робота) в ведомом (виртуальном в открытом 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;

  }
  • Не хочу помечать это как таковое, так как я не знаком, но System::Timers::Timer^ aTimer = gcnew System::Timers::Timer( 100 ); мне кажется C++/CLI? Bart 23.07.2011
  • @Bart Как только вы видите ^, это определенно C++/CLI. Christian Rau 23.07.2011
  • на самом деле, gcnew - гораздо более сильный индикатор C++/CLI. ^ является допустимым оператором в стандартном C++. Ben Voigt 23.07.2011
  • @ Бен Да, ты прав, не думал о xor. Christian Rau 23.07.2011

loopsc++-cliopenglglut

Ответы

Ответ 1 · рейтинг 14 · Christian Rau

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

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

Ответ 2 · рейтинг 4 · datenwolf

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();
}

Ответ 3 · Gideon W

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

Что должно произойти, чтобы вы получали "непрерывное" обновление:

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

Glut продолжается до тех пор, пока программа не будет закрыта.

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

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы