如何持续更新过剩窗口?

发布于 2024-11-26 01:05:40 字数 2070 浏览 3 评论 0原文

我有一个真正的机器人,它正在 open gl 中订购我的虚拟机器人。我想在线显示我的主机器人(真实机器人)在从属机器人(open gl中的虚拟机器人)中的每一个动作,所以我需要不断更新我的过剩窗口,实际上只要真实机器人移动我的虚拟机器人也会移动,所有这些运动应该是在线的。

我总是使用获取数据功能从主站获取数据,但我不知道应该如何更新窗口。

这是我的代码:

************* >***********************< em>********/

  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;

  }

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;

  }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

夜清冷一曲。 2024-12-03 01:05:40

我认为,您可以在更新后调用 glutPostRedisplay,它会安排窗口在返回消息队列后立即重新绘制(当然,使用 GLUT 的显示函数)。

但是,如果您在无限循环中连续轮询机器人数据,则这将不起作用,因为这会连续阻塞程序。您应该做的是使用计时器来安排机器人在短时间内更新,以便在这些更新之间程序可以返回到主事件循环并重绘窗口。或者您可以调用一些函数,它告诉框架访问事件循环。您的代码示例并没有真正解释您目前是如何做到这一点的(或者我只是不熟悉您调用的函数)。

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).

紫瑟鸿黎 2024-12-03 01:05:40

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

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();
}
呆橘 2024-12-03 01:05:40

我会做以下事情。将 glutMainLoop() 视为循环,每次处理一个 getData() 时都会绘制它,它会比您想象的要快。

要获得“持续”更新,您需要执行以下操作:

  1. 处理数据(getData() 然后进行计算)
  2. 重绘(Display() glut 每次都会调用此方法它循环)
  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;
}

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文