在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
结合Opengl和SerialPort控件写了这个姿态显示程序,程序较简单,前面有篇简单的四轴上位机模拟显示四轴状态 也可以看看.本程序界面如下: 我这里是用的 51单片机模拟输出 欧拉角,上位机接收参数,并显示姿态.过几天有时间了解 算传感器中的数据传给上位机.软件就不共享了,核心代码共享给大家,对有一定编程基础的人 有参考作用. 核心代码一:绘图部分,绘制显示的这部分 1 public override void glDraw() 2 { 3 4 // Here's Where We Do All The Drawing 5 GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer 6 GL.glLoadIdentity(); // Reset The Current Modelview Matrix,单位化 7 //gluLookAt本身有一个全局固定坐标系,不随模型的变换而变换,实图变换必需在任何模型变换之前被调用. 8 // GL.glMatrixMode(GL.GL_MODELVIEW); 9 GL.gluLookAt(0.0, 0.0, 0.0, -30.0, -10.0, -100.0, 0.0, 1.0, 0.0); //设置视点 10 //模型变换 是局部坐标系统 11 //局部轴是还物体固连的 12 GL.glTranslatef(-2.0f, -1.0f, -6.0f); 13 14 15 //画圆锥 16 //创建二次曲面对象,X轴的箭头 17 GL.glTranslatef(1.5f, -2.0f, -2.0f); //移动过来再移动回去 18 GL.glRotatef(90, 0.0f, 1.0f, 0.0f); 19 GLUquadric gluNewQuadric; 20 gluNewQuadric = GL.gluNewQuadric(); 21 GL.gluQuadricNormals(gluNewQuadric, GL.GLU_SMOOTH); // 使用平滑法线 22 GL.glColor3f(1.0f, 1.0f, 1.0f); 23 GL.gluCylinder(gluNewQuadric, 0.1f, 0.0f, 0.5f, 32, 32); 24 GL.glRotatef(-90, 0.0f, 1.0f, 0.0f); 25 GL.glTranslatef(-1.5f, 2.0f, 2.0f); 26 //创建二次曲面对象,Y轴的箭头 27 GL.glTranslatef(-2.0f, 1.5f, -2.0f); //移动过来再移动回去 28 GL.glRotatef(-90, 1.0f, 0.0f, 0.0f); 29 GL.glColor3f(1.0f, 1.0f, 1.0f); 30 GL.gluCylinder(gluNewQuadric, 0.1f, 0.0f, 0.5f, 32, 32); 31 GL.glRotatef(90, 1.0f, 0.0f, 0.0f); 32 GL.glTranslatef(2.0f, -1.5f, 2.0f); 33 //创建二次曲面对象,Z轴的箭头 34 GL.glTranslatef(-2.0f, -2.0f, 4.0f); //移动过来再移动回去 35 GL.glColor3f(1.0f, 1.0f, 1.0f); 36 GL.gluCylinder(gluNewQuadric, 0.1f, 0.0f, 0.5f, 32, 32); 37 GL.glTranslatef(2.0f, 2.0f, -4.0f); 38 39 //在这里绘制坐标系统 40 //设置线的粗细 41 GL.glLineWidth(2.0f); 42 GL.glColor3f(1.0f, 1.0f, 1.0f); 43 GL.glBegin(GL.GL_LINES); 44 GL.glVertex3f(-2.0f, -2.0f, -2.0f); 45 GL.glVertex3f(1.5f, -2.0f, -2.0f); 46 GL.glEnd(); 47 48 GL.glColor3f(1.0f, 1.0f, 1.0f); 49 GL.glBegin(GL.GL_LINES); 50 GL.glVertex3f(-2.0f, -2.0f, -2.0f); 51 GL.glVertex3f(-2.0f, 1.5f, -2.0f); 52 GL.glEnd(); 53 54 GL.glColor3f(1.0f, 1.0f, 1.0f); 55 GL.glBegin(GL.GL_LINES); 56 GL.glVertex3f(-2.0f, -2.0f, -2.0f); 57 GL.glVertex3f(-2.0f, -2.0f, 4.0f); 58 GL.glEnd(); 59 60 //绘制正方体 61 62 GL.glRotatef(x, 1.0f, 0.0f, 0.0f); // Rotate The Quad On The X, Y, And Z Axes 63 GL.glRotatef(y, 0.0f, 1.0f, 0.0f); 64 GL.glRotatef(z, 0.0f, 0.0f, 1.0f); 65 66 //一次模型变换会改变局部坐标系统 67 GL.glBindTexture(GL.GL_TEXTURE_2D, textures[0]); 68 GL.glBegin(GL.GL_QUADS); // Draw A Quad 69 70 //1 正前 71 // GL.glColor3f(0.0f, 1.0f, 0.0f); // Set The Color To Gree 72 GL.glTexCoord2f(0.0f, 0.0f); 73 GL.glVertex3f(-1.5f, 0.5f, 1.0f); // 74 GL.glTexCoord2f(1.0f, 0.0f); 75 GL.glVertex3f(1.5f, 0.5f, 1.0f); // 76 GL.glTexCoord2f(1.0f, 1.0f); 77 GL.glVertex3f(1.5f, -0.5f, 1.0f); // 78 GL.glTexCoord2f(0.0f, 1.0f); 79 GL.glVertex3f(-1.5f, -0.5f, 1.0f); // 80 GL.glEnd(); 81 82 //2 后 83 GL.glBindTexture(GL.GL_TEXTURE_2D, textures[1]); 84 GL.glBegin(GL.GL_QUADS); 85 GL.glTexCoord2f(0.0f, 0.0f); 86 GL.glVertex3f(-1.5f, 0.5f, -1.0f); // 87 GL.glTexCoord2f(1.0f, 0.0f); 88 GL.glVertex3f(1.5f, 0.5f, -1.0f); // 89 GL.glTexCoord2f(1.0f, 1.0f); 90 GL.glVertex3f(1.5f, -0.5f, -1.0f); // 91 GL.glTexCoord2f(0.0f, 1.0f); 92 GL.glVertex3f(-1.5f, -0.5f, -1.0f); // 93 GL.glEnd(); 94 //左 95 GL.glBindTexture(GL.GL_TEXTURE_2D, textures[2]); 96 GL.glBegin(GL.GL_QUADS); 97 GL.glTexCoord2f(0.0f, 0.0f); 98 GL.glVertex3f(-1.5f, 0.5f, -1.0f); // 99 GL.glTexCoord2f(1.0f, 0.0f); 100 GL.glVertex3f(-1.5f, -0.5f, -1.0f); // 101 GL.glTexCoord2f(1.0f, 1.0f); 102 GL.glVertex3f(-1.5f, -0.5f, 1.0f); // 103 GL.glTexCoord2f(0.0f, 1.0f); 104 GL.glVertex3f(-1.5f, 0.5f, 1.0f); // 105 GL.glEnd(); 106 //右 107 GL.glBindTexture(GL.GL_TEXTURE_2D, textures[3]); 108 GL.glBegin(GL.GL_QUADS); 109 GL.glTexCoord2f(0.0f, 0.0f); 110 GL.glVertex3f(1.5f, 0.5f, -1.0f); // 111 GL.glTexCoord2f(1.0f, 0.0f); 112 GL.glVertex3f(1.5f, -0.5f, -1.0f); // 113 GL.glTexCoord2f(1.0f, 1.0f); 114 GL.glVertex3f(1.5f, -0.5f, 1.0f); // 115 GL.glTexCoord2f(0.0f, 1.0f); 116 GL.glVertex3f(1.5f, 0.5f, 1.0f); // 117 GL.glEnd(); 118 //上 119 GL.glBindTexture(GL.GL_TEXTURE_2D, textures[4]); 120 GL.glBegin(GL.GL_QUADS); 121 GL.glTexCoord2f(0.0f, 0.0f); 122 GL.glVertex3f(-1.5f, 0.5f, -1.0f); // 123 GL.glTexCoord2f(1.0f, 0.0f); 124 GL.glVertex3f(1.5f, 0.5f, -1.0f); // 125 GL.glTexCoord2f(1.0f, 1.0f); 126 GL.glVertex3f(1.5f, 0.5f, 1.0f); // 127 GL.glTexCoord2f(0.0f, 1.0f); 128 GL.glVertex3f(-1.5f, 0.5f, 1.0f); // 129 GL.glEnd(); 130 //下 131 GL.glBindTexture(GL.GL_TEXTURE_2D, textures[5]); 132 GL.glBegin(GL.GL_QUADS); 133 GL.glTexCoord2f(0.0f, 0.0f); 134 GL.glVertex3f(-1.5f, -0.5f, -1.0f); // 135 GL.glTexCoord2f(1.0f, 0.0f); 136 GL.glVertex3f(1.5f, -0.5f, -1.0f); // 137 GL.glTexCoord2f(1.0f, 1.0f); 138 GL.glVertex3f(1.5f, -0.5f, 1.0f); // 139 GL.glTexCoord2f(0.0f, 1.0f); 140 GL.glVertex3f(-1.5f, -0.5f, 1.0f); // 141 GL.glEnd(); // Done Drawing The Cube 142 143 144 GL.glColor3f(1.0f,1.0f, 1.0f); 145 GL.glBegin(GL.GL_LINES); 146 GL.glVertex3f(2f, 0f, 0.0f); 147 GL.glVertex3f(-2f, 0f, 0f); 148 GL.glEnd(); 149 GL.glColor3f(1.0f, 1.0f, 1.0f); 150 GL.glBegin(GL.GL_LINES); 151 GL.glVertex3f(0f, 2f, 0.0f); 152 GL.glVertex3f(0f, -2f, 0.0f); 153 GL.glEnd(); 154 GL.glColor3f(1.0f, 1.0f, 1.0f); 155 GL.glBegin(GL.GL_LINES); 156 GL.glVertex3f(0f, 0f, 2f); 157 GL.glVertex3f(0f, 0f, -2); 158 GL.glEnd(); 159 160 } 核心代码二:串口数据接收部分 编码为这个 serialPort1.Encoding = Encoding.GetEncoding("iso-8859-1") 否则不能接收 为负的数,比如你传的是 -30 1 private void SynReceiveData(object serialPortobj) 2 { 3 // int lengh; 4 char[] receive_char = new char[9]; 5 while (true) 6 { 7 try 8 { 9 data = serialPort1.ReadLine(); 10 } 11 catch(Exception ex) 12 { 13 break; 14 } 15 // int temp_int = serialPort1.Read(char_read,0,9); 16 // data = serialPort1.read 17 //string temp = serialPort1.ReadLine(); 18 if (data.Length == 9) 19 { 20 receive_char = data.ToArray(); 21 if (receive_char[0] == 'a') 22 { 23 // receive_char[1] = (char)0xff; 24 // receive_char[2] = (char)0xf1; 25 angle[0] = (Int16)((Int16)(receive_char[1] << 8) + (Int16)receive_char[2]); //Pitch 26 angle[1] = (Int16)((Int16)(receive_char[4] << 8) + (Int16)receive_char[5]); //Roll 27 angle[2] = (Int16)((Int16)(receive_char[7] << 8) + (Int16)receive_char[8]); // Yaw 28 myGLView.X = (int)angle[0]; //opengl 类中的角度 29 myGLView.Y = (int)angle[1]; 30 myGLView.Z = (int)angle[2]; 31 SetText(angle[0].ToString(), angle[1].ToString(), angle[2].ToString()); 32 } 33 } 34 35 } 36 } 核心代码三:跨线程访问题."线程间操作无效: 从不是创建控件“label1”的线程访问它。" 1 /// <summary> 2 /// 跨线程调用 3 /// </summary> 4 /// <param name="text1"></param> 5 /// <param name="text2"></param> 6 /// <param name="text3"></param> 7 private void SetText(string text1, string text2, string text3) 8 { 9 try 10 { 11 if (label1.InvokeRequired) 12 { 13 SetTextHandler set = new SetTextHandler(SetText);//委托的方法参数应和SetText一致 14 label1.BeginInvoke(set, new object[] { text1, text2, text3 }); //此方法第二参数用于传入方法,代替形参text 15 } 16 else 17 { 18 label1.Text = "Pitch:" + text1; 19 } 20 if (label2.InvokeRequired) 21 { 22 SetTextHandler set = new SetTextHandler(SetText);//委托的方法参数应和SetText一致 23 label1.Invoke(set, new object[] { text1, text2, text3 }); //此方法第二参数用于传入方法,代替形参text 24 } 25 else 26 { 27 label2.Text = "Roll :" + text2; 28 } 29 if (label3.InvokeRequired) 30 { 31 SetTextHandler set = new SetTextHandler(SetText);//委托的方法参数应和SetText一致 32 label3.Invoke(set, new object[] { text1, text2, text3 }); //此方法第二参数用于传入方法,代替形参text 33 } 34 else 35 { 36 label3.Text = "Yaw :" + text3; 37 } 38 } 39 catch(Exception ex) 40 { 41 return; 42 } 43 }
上位传给上位机数据格式 'a''+''+''b''+''+''c''+''+''\n' a 是单个字符 '+'是传送的数据 ,高8位在前. 下位机51程序如下: #include <REG51.H> #include "com.h" void main() { unsigned char *array; unsigned char par[10]; bit flag_1=1,flag_2=1,flag_3=1; int pitch=0,yaw=0,roll=1; int i,k; init_uart(); while(1) { par[0]='a'; par[3]='b'; par[6]='c'; par[9]='\n'; //模拟生成 pitch if(flag_1) { pitch++; //ReadLine()方法不能读取大于126的char if(pitch==90)flag_1=0; } else { pitch--; if(pitch==-90)flag_1=1; } //模拟生成 roll if(flag_2) { roll++; if(roll==90)flag_2=0; } else { roll--; if(roll==-90)flag_2=1; } //模拟生成 yaw if(flag_3) { yaw++; if(yaw==90)flag_3=0; } else { yaw--; if(yaw==-90) flag_3=1; } par[1]=(pitch&0xff00)>>8; par[2]=pitch&0x00ff; par[4]=(roll&0xff00)>>8; par[5]=roll&0x00ff; par[7]=(yaw&0xff00)>>8; par[8]=yaw&0x00ff; for(i=0 ; i<10;i++) { sendchar(par[i]); //这里是把数据从串口发送出去 } for( k=50;k>0;k--) { int j=50; while(j--); } } } 总结: 目前程序写到这只是一个过度阶段,下面是用 51单片机或是写ARM9裸机程序,读取姿态传感器中数据计算出欧拉角或着是四元数, 再传给上位机. 博文为本人所写.转载请表明出处. |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论