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

    再传给上位机.

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

  • 相关阅读:
    深入理解计算机操作系统(十)
    深入理解计算机操作系统(九)
    深入理解计算机操作系统(八)
    深入理解计算机操作系统(七)
    深入理解计算机操作系统(六)
    深入理解计算机操作系统(五)
    mysql创建新用户
    沙特女性终于开车上路,仍有男性对此不爽
    为什么人们爱听有声书?
    韩流来袭,英文歌曲的垄断地位被撼动
  • 原文地址:https://www.cnblogs.com/dreamfactory/p/2846683.html
Copyright © 2020-2023  润新知