C# 姿态显示程序 Opengl SerialPort
2013-01-05 20:58
288 查看
结合Opengl和SerialPort控件写了这个姿态显示程序,程序较简单,前面有篇简单的四轴上位机模拟显示四轴状态
也可以看看.本程序界面如下:
我这里是用的 51单片机模拟输出 欧拉角,上位机接收参数,并显示姿态.过几天有时间了解
算传感器中的数据传给上位机.软件就不共享了,核心代码共享给大家,对有一定编程基础的人
有参考作用.
核心代码一:绘图部分,绘制显示的这部分
核心代码二:串口数据接收部分 编码为这个 serialPort1.Encoding = Encoding.GetEncoding("iso-8859-1") 否则不能接收 为负的数,比如你传的是 -30
核心代码三:跨线程访问题."线程间操作无效: 从不是创建控件“label1”的线程访问它。"
上位传给上位机数据格式 'a''+''+''b''+''+''c''+''+''\n' a 是单个字符 '+'是传送的数据 ,高8位在前.
下位机51程序如下:
总结: 目前程序写到这只是一个过度阶段,下面是用 51单片机或是写ARM9裸机程序,读取姿态传感器中数据计算出欧拉角或着是四元数,
再传给上位机.
博文为本人所写.转载请表明出处.
也可以看看.本程序界面如下:
我这里是用的 51单片机模拟输出 欧拉角,上位机接收参数,并显示姿态.过几天有时间了解
算传感器中的数据传给上位机.软件就不共享了,核心代码共享给大家,对有一定编程基础的人
有参考作用.
核心代码一:绘图部分,绘制显示的这部分
public override void glDraw() { // Here's Where We Do All The Drawing GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer GL.glLoadIdentity(); // Reset The Current Modelview Matrix,单位化 //gluLookAt本身有一个全局固定坐标系,不随模型的变换而变换,实图变换必需在任何模型变换之前被调用. // GL.glMatrixMode(GL.GL_MODELVIEW); GL.gluLookAt(0.0, 0.0, 0.0, -30.0, -10.0, -100.0, 0.0, 1.0, 0.0); //设置视点 //模型变换 是局部坐标系统 //局部轴是还物体固连的 GL.glTranslatef(-2.0f, -1.0f, -6.0f); //画圆锥 //创建二次曲面对象,X轴的箭头 GL.glTranslatef(1.5f, -2.0f, -2.0f); //移动过来再移动回去 GL.glRotatef(90, 0.0f, 1.0f, 0.0f); GLUquadric gluNewQuadric; gluNewQuadric = GL.gluNewQuadric(); GL.gluQuadricNormals(gluNewQuadric, GL.GLU_SMOOTH); // 使用平滑法线 GL.glColor3f(1.0f, 1.0f, 1.0f); GL.gluCylinder(gluNewQuadric, 0.1f, 0.0f, 0.5f, 32, 32); GL.glRotatef(-90, 0.0f, 1.0f, 0.0f); GL.glTranslatef(-1.5f, 2.0f, 2.0f); //创建二次曲面对象,Y轴的箭头 GL.glTranslatef(-2.0f, 1.5f, -2.0f); //移动过来再移动回去 GL.glRotatef(-90, 1.0f, 0.0f, 0.0f); GL.glColor3f(1.0f, 1.0f, 1.0f); GL.gluCylinder(gluNewQuadric, 0.1f, 0.0f, 0.5f, 32, 32); GL.glRotatef(90, 1.0f, 0.0f, 0.0f); GL.glTranslatef(2.0f, -1.5f, 2.0f); //创建二次曲面对象,Z轴的箭头 GL.glTranslatef(-2.0f, -2.0f, 4.0f); //移动过来再移动回去 GL.glColor3f(1.0f, 1.0f, 1.0f); GL.gluCylinder(gluNewQuadric, 0.1f, 0.0f, 0.5f, 32, 32); GL.glTranslatef(2.0f, 2.0f, -4.0f); //在这里绘制坐标系统 //设置线的粗细 GL.glLineWidth(2.0f); GL.glColor3f(1.0f, 1.0f, 1.0f); GL.glBegin(GL.GL_LINES); GL.glVertex3f(-2.0f, -2.0f, -2.0f); GL.glVertex3f(1.5f, -2.0f, -2.0f); GL.glEnd(); GL.glColor3f(1.0f, 1.0f, 1.0f); GL.glBegin(GL.GL_LINES); GL.glVertex3f(-2.0f, -2.0f, -2.0f); GL.glVertex3f(-2.0f, 1.5f, -2.0f); GL.glEnd(); GL.glColor3f(1.0f, 1.0f, 1.0f); GL.glBegin(GL.GL_LINES); GL.glVertex3f(-2.0f, -2.0f, -2.0f); GL.glVertex3f(-2.0f, -2.0f, 4.0f); GL.glEnd(); //绘制正方体 GL.glRotatef(x, 1.0f, 0.0f, 0.0f); // Rotate The Quad On The X, Y, And Z Axes GL.glRotatef(y, 0.0f, 1.0f, 0.0f); GL.glRotatef(z, 0.0f, 0.0f, 1.0f); //一次模型变换会改变局部坐标系统 GL.glBindTexture(GL.GL_TEXTURE_2D, textures[0]); GL.glBegin(GL.GL_QUADS); // Draw A Quad //1 正前 // GL.glColor3f(0.0f, 1.0f, 0.0f); // Set The Color To Gree GL.glTexCoord2f(0.0f, 0.0f); GL.glVertex3f(-1.5f, 0.5f, 1.0f); // GL.glTexCoord2f(1.0f, 0.0f); GL.glVertex3f(1.5f, 0.5f, 1.0f); // GL.glTexCoord2f(1.0f, 1.0f); GL.glVertex3f(1.5f, -0.5f, 1.0f); // GL.glTexCoord2f(0.0f, 1.0f); GL.glVertex3f(-1.5f, -0.5f, 1.0f); // GL.glEnd(); //2 后 GL.glBindTexture(GL.GL_TEXTURE_2D, textures[1]); GL.glBegin(GL.GL_QUADS); GL.glTexCoord2f(0.0f, 0.0f); GL.glVertex3f(-1.5f, 0.5f, -1.0f); // GL.glTexCoord2f(1.0f, 0.0f); GL.glVertex3f(1.5f, 0.5f, -1.0f); // GL.glTexCoord2f(1.0f, 1.0f); GL.glVertex3f(1.5f, -0.5f, -1.0f); // GL.glTexCoord2f(0.0f, 1.0f); GL.glVertex3f(-1.5f, -0.5f, -1.0f); // GL.glEnd(); //左 GL.glBindTexture(GL.GL_TEXTURE_2D, textures[2]); GL.glBegin(GL.GL_QUADS); GL.glTexCoord2f(0.0f, 0.0f); GL.glVertex3f(-1.5f, 0.5f, -1.0f); // GL.glTexCoord2f(1.0f, 0.0f); GL.glVertex3f(-1.5f, -0.5f, -1.0f); // GL.glTexCoord2f(1.0f, 1.0f); GL.glVertex3f(-1.5f, -0.5f, 1.0f); // GL.glTexCoord2f(0.0f, 1.0f); GL.glVertex3f(-1.5f, 0.5f, 1.0f); // GL.glEnd(); //右 GL.glBindTexture(GL.GL_TEXTURE_2D, textures[3]); GL.glBegin(GL.GL_QUADS); GL.glTexCoord2f(0.0f, 0.0f); GL.glVertex3f(1.5f, 0.5f, -1.0f); // GL.glTexCoord2f(1.0f, 0.0f); GL.glVertex3f(1.5f, -0.5f, -1.0f); // GL.glTexCoord2f(1.0f, 1.0f); GL.glVertex3f(1.5f, -0.5f, 1.0f); // GL.glTexCoord2f(0.0f, 1.0f); GL.glVertex3f(1.5f, 0.5f, 1.0f); // GL.glEnd(); //上 GL.glBindTexture(GL.GL_TEXTURE_2D, textures[4]); GL.glBegin(GL.GL_QUADS); GL.glTexCoord2f(0.0f, 0.0f); GL.glVertex3f(-1.5f, 0.5f, -1.0f); // GL.glTexCoord2f(1.0f, 0.0f); GL.glVertex3f(1.5f, 0.5f, -1.0f); // GL.glTexCoord2f(1.0f, 1.0f); GL.glVertex3f(1.5f, 0.5f, 1.0f); // GL.glTexCoord2f(0.0f, 1.0f); GL.glVertex3f(-1.5f, 0.5f, 1.0f); // GL.glEnd(); //下 GL.glBindTexture(GL.GL_TEXTURE_2D, textures[5]); GL.glBegin(GL.GL_QUADS); GL.glTexCoord2f(0.0f, 0.0f); GL.glVertex3f(-1.5f, -0.5f, -1.0f); // GL.glTexCoord2f(1.0f, 0.0f); GL.glVertex3f(1.5f, -0.5f, -1.0f); // GL.glTexCoord2f(1.0f, 1.0f); GL.glVertex3f(1.5f, -0.5f, 1.0f); // GL.glTexCoord2f(0.0f, 1.0f); GL.glVertex3f(-1.5f, -0.5f, 1.0f); // GL.glEnd(); // Done Drawing The Cube GL.glColor3f(1.0f,1.0f, 1.0f); GL.glBegin(GL.GL_LINES); GL.glVertex3f(2f, 0f, 0.0f); GL.glVertex3f(-2f, 0f, 0f); GL.glEnd(); GL.glColor3f(1.0f, 1.0f, 1.0f); GL.glBegin(GL.GL_LINES); GL.glVertex3f(0f, 2f, 0.0f); GL.glVertex3f(0f, -2f, 0.0f); GL.glEnd(); GL.glColor3f(1.0f, 1.0f, 1.0f); GL.glBegin(GL.GL_LINES); GL.glVertex3f(0f, 0f, 2f); GL.glVertex3f(0f, 0f, -2); GL.glEnd(); }
核心代码二:串口数据接收部分 编码为这个 serialPort1.Encoding = Encoding.GetEncoding("iso-8859-1") 否则不能接收 为负的数,比如你传的是 -30
private void SynReceiveData(object serialPortobj) { // int lengh; char[] receive_char = new char[9]; while (true) { try { data = serialPort1.ReadLine(); } catch(Exception ex) { break; } // int temp_int = serialPort1.Read(char_read,0,9); // data = serialPort1.read //string temp = serialPort1.ReadLine(); if (data.Length == 9) { receive_char = data.ToArray(); if (receive_char[0] == 'a') { // receive_char[1] = (char)0xff; // receive_char[2] = (char)0xf1; angle[0] = (Int16)((Int16)(receive_char[1] << 8) + (Int16)receive_char[2]); //Pitch angle[1] = (Int16)((Int16)(receive_char[4] << 8) + (Int16)receive_char[5]); //Roll angle[2] = (Int16)((Int16)(receive_char[7] << 8) + (Int16)receive_char[8]); // Yaw myGLView.X = (int)angle[0]; //opengl 类中的角度 myGLView.Y = (int)angle[1]; myGLView.Z = (int)angle[2]; SetText(angle[0].ToString(), angle[1].ToString(), angle[2].ToString()); } } } }
核心代码三:跨线程访问题."线程间操作无效: 从不是创建控件“label1”的线程访问它。"
/// <summary> /// 跨线程调用 /// </summary> /// <param name="text1"></param> /// <param name="text2"></param> /// <param name="text3"></param> private void SetText(string text1, string text2, string text3) { try { if (label1.InvokeRequired) { SetTextHandler set = new SetTextHandler(SetText);//委托的方法参数应和SetText一致 label1.BeginInvoke(set, new object[] { text1, text2, text3 }); //此方法第二参数用于传入方法,代替形参text } else { label1.Text = "Pitch:" + text1; } if (label2.InvokeRequired) { SetTextHandler set = new SetTextHandler(SetText);//委托的方法参数应和SetText一致 label1.Invoke(set, new object[] { text1, text2, text3 }); //此方法第二参数用于传入方法,代替形参text } else { label2.Text = "Roll :" + text2; } if (label3.InvokeRequired) { SetTextHandler set = new SetTextHandler(SetText);//委托的方法参数应和SetText一致 label3.Invoke(set, new object[] { text1, text2, text3 }); //此方法第二参数用于传入方法,代替形参text } else { label3.Text = "Yaw :" + text3; } } catch(Exception ex) { return; } }
上位传给上位机数据格式 '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裸机程序,读取姿态传感器中数据计算出欧拉角或着是四元数,
再传给上位机.
博文为本人所写.转载请表明出处.
相关文章推荐
- C#的SerialPort串口程序设计总结
- C#SerialPort如何读取串口数据并显示在TextBox上
- 各位C#高手,我编了个小小关于TreeView控件的程序但就是在窗口上显示不出来.帮忙解决下.
- 如何用Nsight调试C# OpenGL程序
- [转]微软SerialPort秘籍[SerialPort为什么死锁程序的分析]
- C# 实现程序只启动一次(多次运行激活第一个实例,使其获得焦点,并在最前端显示)
- C#serialport收到数据实时插入数据库 datagridview更新一行 提高效率
- C#调用C++用类封装的coin3d 3维显示程序
- C# SerialPort 串口通讯 通过计算机232来和外部设备通讯 DL/T1997 DL/T2007 通讯协议
- C# SerialPort常用的属性和方法
- C# winForm程序开机启动和托盘显示 (转http://blog.csdn.net/xinyue3054/article/details/6599508)
- 系统服务显示EXE程序(C#)
- 利用第三方qextserialport类完成QT下串口MyComm程序
- c#Winform程序,让pictureBox显示图像(包含GIF),并且不被占用,能即时删除图片。
- C#Winform实现程序关闭隐藏窗体,二次程序启动时显示
- C#程序通信过程中 突然停止 只主窗口显示
- C#串口通信程序SerialPort类
- c# 程序只能运行一次(多次运行只能打开同一个程序) 并激活第一个实例,使其获得焦点,并在最前端显示.
- PIC24, dsPIC单片机端C语言serial bootloader和PC端C#语言bootloader串口通信程序
- win Qt qextserialport 编写串口通信程序全程图文讲解