首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在接收UDP数据时移动OpenGL机械臂?

在接收UDP数据时移动OpenGL机械臂?
EN

Stack Overflow用户
提问于 2018-07-08 08:45:19
回答 1查看 287关注 0票数 0

我有这段代码,主要的想法是绘制一个机器人手臂,并在通过9090端口使用UDP接收到数据时移动它。

我想弄清楚为什么在显示机械臂后,控制台上没有显示消息。

此外,我想知道如何在if(number%2 ==0)之后修改代码以移动手臂。

代码语言:javascript
复制
#include <GL/glut.h>
#include <math.h>
#define BASE_HEIGHT 4.0/2
#define BASE_RADIUS 1.0/2
#define HEAD_HEIGHT 1.25/2
#define HEAD_RADIUS 0.75/2
#define NECK_HEIGHT 0.5/2
#define EYE_LEVEL 0.75/2
#define NOSE_LENGTH 0.5/2
#define LOWER_ARM_HEIGHT 2.0/2
#define LOWER_ARM_WIDTH 0.5/2
#define UPPER_ARM_HEIGHT 1.25/2
#define UPPER_ARM_WIDTH 0.5/2
#define ARM_TRANSLATION 0.22/2
#define alpha 0.0
#define pi 3.14159265
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <netdb.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <netdb.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define BUFSIZE 2048
//***********************
    struct sockaddr_in myaddr;  /* our address */
    struct sockaddr_in remaddr; /* remote address */
    socklen_t addrlen = sizeof(remaddr);        /* length of addresses */
    int recvlen;            /* # bytes received */
    int fd;             /* our socket */
    unsigned char buf[BUFSIZE]; /* receive buffer */


#define SERVICE_PORT    9090 


int a2i(unsigned char *s)
{
 int sign=1;
 if(*s == '-')
        sign = -1;
 s++;
 int num=0;
 while(*s)
  {
    num=((*s)-'0')+num*10;
    s++;   
  }
 return num*sign;
}
// The robot arm is specified by (1) the angle that the upper arm makes
// relative to the x-axis, called shoulderAngle, and (2) the angle that the
// lower arm makes relative to the upper arm, called elbowAngle.  These angles
// are adjusted in 5 degree increments by a keyboard callback.
static int shoulderAngle = 0, elbowAngle = 0;

// Handles the keyboard event: the left and right arrows bend the elbow, the
// up and down keys bend the shoulder.
void special(int key, int, int) {
  switch (key) {
    case GLUT_KEY_LEFT: (elbowAngle += 5) %= 360; break;
    case GLUT_KEY_RIGHT: (elbowAngle -= 5) %= 360; break;
    case GLUT_KEY_UP: (shoulderAngle += 5) %= 360; break;
    case GLUT_KEY_DOWN: (shoulderAngle -= 5) %= 360; break;
    default: return;
  }
  glutPostRedisplay();
}

// wireBox(w, h, d) makes a wireframe box with width w, height h and
// depth d centered at the origin.  It uses the GLUT wire cube function.
// The calls to glPushMatrix and glPopMatrix are essential here; they enable
// this function to be called from just about anywhere and guarantee that
// the glScalef call does not pollute code that follows a call to myWireBox.
void wireBox(GLdouble width, GLdouble height, GLdouble depth) {
  glPushMatrix();
  glScalef(width, height, depth);
  glutWireCube(1.0);
  glPopMatrix();
}

// Displays the arm in its current position and orientation.  The whole
// function is bracketed by glPushMatrix and glPopMatrix calls because every
// time we call it we are in an "environment" in which a gluLookAt is in
// effect.  (Note that in particular, replacing glPushMatrix with
// glLoadIdentity makes you lose the camera setting from gluLookAt).
void display() {

  glClear(GL_COLOR_BUFFER_BIT);
  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();

  // Draw the upper arm, rotated shoulder degrees about the z-axis.  Note that
  // the thing about glutWireBox is that normally its origin is in the middle
  // of the box, but we want the "origin" of our box to be at the left end of
  // the box, so it needs to first be shifted 1 unit in the x direction, then
  // rotated.
  glRotatef((GLfloat)shoulderAngle, 0.0, 0.0, 1.0);
  glTranslatef(1.0, 0.0, 0.0);
  wireBox(2.0, 0.4, 1.0);

  // Now we are ready to draw the lower arm.  Since the lower arm is attached
  // to the upper arm we put the code here so that all rotations we do are
  // relative to the rotation that we already made above to orient the upper
  // arm.  So, we want to rotate elbow degrees about the z-axis.  But, like
  // before, the anchor point for the rotation is at the end of the box, so
  // we translate <1,0,0> before rotating.  But after rotating we have to
  // position the lower arm at the end of the upper arm, so we have to
  // translate it <1,0,0> again.
  glTranslatef(1.0, 0.0, 0.0);
  glRotatef((GLfloat)elbowAngle, 0.0, 0.0, 1.0);
  glTranslatef(1.0, 0.0, 0.0);
  wireBox(2.0, 0.4, 1.0);

  glPopMatrix();
  glFlush();
}

// Handles the reshape event by setting the viewport so that it takes up the
// whole visible region, then sets the projection matrix to something reason-
// able that maintains proper aspect ratio.
void reshape(GLint w, GLint h) {
  glViewport(0, 0, w, h);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(65.0, GLfloat(w)/GLfloat(h), 1.0, 20.0);
}

// Perfroms application specific initialization: turn off smooth shading,
// sets the viewing transformation once and for all.  In this application we
// won't be moving the camera at all, so it makes sense to do this.
void init() {
  glShadeModel(GL_FLAT);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  gluLookAt(1,2,8, 0,0,0, 0,1,0);
}

// Initializes GLUT, the display mode, and main window; registers callbacks;
// does application initialization; enters the main event loop.
int main(int argc, char** argv) {



    /* create a UDP socket */

    if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        perror("cannot create socket\n");
        return 0;
    }

    /* bind the socket to any valid IP address and a specific port */

    memset((char *)&myaddr, 0, sizeof(myaddr));
    myaddr.sin_family = AF_INET;
    myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    myaddr.sin_port = htons(SERVICE_PORT);

    if (bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) {
        perror("bind failed");
        return 0;
    }


  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
  glutInitWindowPosition(80, 80);
  glutInitWindowSize(800, 600);
  glutCreateWindow("Robot Arm");
  glutDisplayFunc(display);
  glutReshapeFunc(reshape);
  glutSpecialFunc(special);
  init();
  glutMainLoop();

    /* now loop, receiving data and printing what we received */
    for (;;) {
        printf("waiting on port %d\n", SERVICE_PORT);
        recvlen = recvfrom(fd, buf, BUFSIZE, 0, (struct sockaddr *)&remaddr, &addrlen);
        printf("received %d bytes\n", recvlen);



        if (recvlen > 0) {
            buf[recvlen] = 0;
            printf("received message: \"%s\"\n", buf);
            int number = a2i( buf );
            if(number%2 ==0) {
            printf("pair message: \"%s\"\n", buf);





                    }
        }
    }
    /* never exits */

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


}
EN

回答 1

Stack Overflow用户

发布于 2018-07-08 11:21:23

glutMainLoop()从不返回:

glutMainLoop进入GLUT事件处理循环。在GLUT程序中,此例程最多只能调用一次。一旦调用,此例程将永远不会返回。它将在必要时调用任何已注册的回调。

您有几个选项:

  • 切换到非阻塞套接字,并在glutIdleFunc()回调中服务您的网络连接。
  • 使用FreeGLUTglutMainLoopEvent()和朋友来夺回对事件循环的一些控制。注意使用阻塞套接字在网络套接字上阻塞等待多长时间,并启动线程来服务网络连接;如何将状态更新从线程传送到主程序由您决定。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51228015

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档