C# 姿态显示程序 Opengl SerialPort

  结合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裸机程序,读取姿态传感器中数据计算出欧拉角或着是四元数,

再传给上位机.

博文为本人所写.转载请表明出处.

原文地址:https://www.cnblogs.com/dreamfactory/p/2846683.html