用户
 找回密码
 立即注册

QQ登录

只需一步,快速开始

点击进入授权页面

只需一步,快速开始

  • QQ空间
  • 回复
  • 收藏
  • TA的每日心情
    慵懒
    2017-7-16 11:47
  • 签到天数: 44 天

    [LV.5]常住居民I

    奈何col 攻城狮 2017-3-12 17:35 楼主
    数据可视化是当前计算机应用的热门方向,通常是将真实世界中的数据通过计算机进行处理,转换成图形图像的方式呈现。本节将会使用Processing,将Genuino 101的姿态数据呈现到电脑上。
    Processing是一门针对数字艺术设计的计算语言,是Java 语言的延伸,语法简单易懂。现已被广泛应用于视觉艺术、数据可视化、原型制作、上位机开发等领域,有成千上万的学生、艺术家、设计师、爱好者都在学习Processing或使用Processing进行开发
    利用Processing,可以轻松将Arduino采集到的数据以可视化的方式呈现出来。实现思路为,使用Genuino 101采集IMU模块数据,并串口输出AHRS姿态数据到PC,再利用Processing绘制出Genuino 101模型,并同步显示姿态变化。
    Processing 可以在 Windows、MAC OS、Linux 等操作系统上使用,目前最新版本为Processing 3。Processing开源且免费,下载地址为:
    社区的资源库下载

             本节示例程序来自Madgwick库示例,可通过Arduino IDE菜单>文件>示例>Madgwick>Visualize101 打开。Genuino101端可视化示例程序如下:
    #include <CurieIMU.h>
    #include <MadgwickAHRS.h>

    Madgwick filter;
    unsigned long microsPerReading, microsPrevious;
    float accelScale, gyroScale;

    void setup() {
      Serial.begin(9600);

      // 初始化IMU和滤波器
      CurieIMU.begin();
      CurieIMU.setGyroRate(25);
      CurieIMU.setAccelerometerRate(25);
      filter.begin(25);

      // 设置加速度计测量范围为2G
      CurieIMU.setAccelerometerRange(2);
      // 设置陀螺仪测量范围为+/-250°/s
      CurieIMU.setGyroRange(250);

      // 初始化用于调整更新速率的变量
      microsPerReading = 1000000 / 25;
      microsPrevious = micros();

      //陀螺仪校准
      Serial.print("Starting Gyroscope calibration and enabling offset compensation...");
      CurieIMU.autoCalibrateGyroOffset();
      Serial.println(" Done");

      //加速度计校准
      Serial.print("Starting Acceleration calibration and enabling offset compensation...");
      CurieIMU.autoCalibrateAccelerometerOffset(X_AXIS, 0);
      CurieIMU.autoCalibrateAccelerometerOffset(Y_AXIS, 0);
      CurieIMU.autoCalibrateAccelerometerOffset(Z_AXIS, 1);
      Serial.println(" Done");
    }

    void loop() {
      int aix, aiy, aiz;
      int gix, giy, giz;
      float ax, ay, az;
      float gx, gy, gz;
      float roll, pitch, heading;
      unsigned long microsNow;

      // 按设定读取频率,读取数据并更新滤波器
      microsNow = micros();
      if (microsNow - microsPrevious >= microsPerReading) {

        // 读取IMU原始数据
        CurieIMU.readMotionSensor(aix, aiy, aiz, gix, giy, giz);

        // convert from raw data to gravity and degrees/second units
        ax = convertRawAcceleration(aix);
        ay = convertRawAcceleration(aiy);
        az = convertRawAcceleration(aiz);
        gx = convertRawGyro(gix);
        gy = convertRawGyro(giy);
        gz = convertRawGyro(giz);

        // 更新滤波器,并进行相关运算
        filter.updateIMU(gx, gy, gz, ax, ay, az);

        // 获取并输出AHRS姿态数据
        roll = filter.getRoll();
        pitch = filter.getPitch();
        heading = filter.getYaw();
        Serial.print("Orientation: ");
        Serial.print(heading);
        Serial.print(" ");
        Serial.print(pitch);
        Serial.print(" ");
        Serial.println(roll);

        // 计时
        microsPrevious = microsPrevious + microsPerReading;
      }
    }

    float convertRawAcceleration(int aRaw) {
      float a = (aRaw * 2.0) / 32768.0;
      return a;
    }

    float convertRawGyro(int gRaw) {
      float g = (gRaw * 250.0) / 32768.0;
      return g;
    }


    本书篇幅有限,这里不对Processing编程进行过多讲解,关于Processing编程相关资料可见Processing官方网站:https://processing.org/
    Processing端程序如下:
    [Java] 纯文本查看 复制代码
    import processing.serial.*;
    Serial myPort;
    
    float yaw = 0.0;
    float pitch = 0.0;
    float roll = 0.0;
    
    void setup()
    {
      size(600, 500, P3D);
    
      // if you have only ONE serial port active
      //myPort = new Serial(this, Serial.list()[0], 9600); // if you have only ONE serial port active
    
      // if you know the serial port name
      myPort = new Serial(this, "COM5", 9600);                    // Windows
      //myPort = new Serial(this, "/dev/ttyACM0", 9600);             // Linux
      //myPort = new Serial(this, "/dev/cu.usbmodem1217321", 9600);  // Mac
    
      textSize(16); // set text size
      textMode(SHAPE); // set text mode to shape
    }
    
    void draw()
    {
      serialEvent();  // read and parse incoming serial message
      background(255); // set background to white
      lights();
    
      translate(width/2, height/2); // set position to centre
    
      pushMatrix(); // begin object
    
      float c1 = cos(radians(roll));
      float s1 = sin(radians(roll));
      float c2 = cos(radians(pitch));
      float s2 = sin(radians(pitch));
      float c3 = cos(radians(yaw));
      float s3 = sin(radians(yaw));
      applyMatrix( c2*c3, s1*s3+c1*c3*s2, c3*s1*s2-c1*s3, 0,
                   -s2, c1*c2, c2*s1, 0,
                   c2*s3, c1*s2*s3-c3*s1, c1*c3+s1*s2*s3, 0,
                   0, 0, 0, 1);
    
      drawArduino();
    
      popMatrix(); // end of object
    
      // Print values to console
      print(roll);
      print("\t");
      print(pitch);
      print("\t");
      print(yaw);
      println();
    }
    
    void serialEvent()
    {
      int newLine = 13; // new line character in ASCII
      String message;
      do {
        message = myPort.readStringUntil(newLine); // read from port until new line
        if (message != null) {
          String[] list = split(trim(message), " ");
          if (list.length >= 4 && list[0].equals("Orientation:")) {
            yaw = float(list[1]); // convert to float yaw
            pitch = float(list[2]); // convert to float pitch
            roll = float(list[3]); // convert to float roll
          }
        }
      } while (message != null);
    }
    
    void drawArduino()
    {
      /* function contains shape(s) that are rotated with the IMU */
      stroke(0, 90, 90); // set outline colour to darker teal
      fill(0, 130, 130); // set fill colour to lighter teal
      box(300, 10, 200); // draw Arduino board base shape
    
      stroke(0); // set outline colour to black
      fill(80); // set fill colour to dark grey
    
      translate(60, -10, 90); // set position to edge of Arduino box
      box(170, 20, 10); // draw pin header as box
    
      translate(-20, 0, -180); // set position to other edge of Arduino box
      box(210, 20, 10); // draw other pin header as box
    }
    


    需要注意的是,Processing与Genuino 101间使用串口通信,在Processing程序中需要指定串口号,不同操作系统中串口表示方式不同。例如,windows中我们使用如下语句实例化串口对象。
    [C++] 纯文本查看 复制代码
    myPort = new Serial(this,  "COM5", 9600);


    将以上代码复制到Processing代码编辑区中,并点击运行按钮运行按钮运行程序,就可以看到如图的界面。尝试转动Genuino 101,可见其中3D模型跟随Genuino 101同步转动。


    processing.jpg
    -------------------------------------------------------------------------------------------------
    本教程分为五部分:
    1.配置IMU及获取数据   http://www.arduino.cn/thread-42850-1-1.html
    2.结算AHRS姿态   http://www.arduino.cn/thread-42851-1-1.html
    3.姿态数据可视化   http://www.arduino.cn/thread-42852-1-1.html
    4.IMU中断检测   http://www.arduino.cn/thread-42853-1-1.html
    5.神经元与机器学习   http://www.arduino.cn/thread-42854-1-1.html
    如果以上内容对你有帮助,你可以通过打赏支持作者
    发现这个库有一些问题,我把101放在桌面不动,madgwick计算出的heading随时间漂移。旋转101时,processing中图形的旋转方向也不一致。截图中随时间线性增加的就是heading的值

    零漂.PNG 零漂2.PNG


    点评

    1.初始要面朝上平放 2.有漂移是正常的  详情 回复 发表于 2017-3-14 21:11
    WESTCENT 发表于 2017-3-14 20:39
    发现这个库有一些问题,我把101放在桌面不动,madgwick计算出的heading随时间漂移。旋转101时,processing ...

    1.初始要面朝上平放
    2.有漂移是正常的
    如果以上内容对你有帮助,你可以通过打赏支持作者
    WESTCENT 发表于 2017-3-14 20:39
    发现这个库有一些问题,我把101放在桌面不动,madgwick计算出的heading随时间漂移。旋转101时,processing ...

    的确是面朝上放置,但是processing显示的图形几分钟就能原地转一圈,实在是难以相信

    点评

    是这样的,个别传感器就是飘的厉害,应该可以软件优化,只是我不会  详情 回复 发表于 2017-3-15 09:15
    WESTCENT 发表于 2017-3-14 21:19
    的确是面朝上放置,但是processing显示的图形几分钟就能原地转一圈,实在是难以相信 ...

    是这样的,个别传感器就是飘的厉害,应该可以软件优化,只是我不会
    如果以上内容对你有帮助,你可以通过打赏支持作者
    本帖最后由 buganfuhua 于 2017-3-15 23:24 编辑
    Arduino:1.8.1 (Windows 10), 开发板:"Arduino/Genuino 101"

    C:\Users\Z\AppData\Local\Temp\arduino_modified_sketch_577904\Blink.ino:2:26: fatal error: MadgwickAHRS.h: No such file or directory

    #include <MadgwickAHRS.h>

                              ^

    compilation terminated.

    exit status 1
    为开发板 Arduino/Genuino 101 编译时出错。

    在文件 -> 首选项开启
    “编译过程中显示详细输出”选项
    这份报告会包含更多信息。
    这是什么情况呢 还有 我在实例库中没发现Madgwick文档……




    点评

    本教程分为五部分: 1.配置IMU及获取数据 http://www.arduino.cn/thread-42850-1-1.html 2.结算AHRS姿态 http://www.arduino.cn/thread-42851-1-1.html 3.姿态数据可视化 http://www.arduino.cn/thread-42852-  详情 回复 发表于 2017-3-15 23:36

    本教程分为五部分:
    1.配置IMU及获取数据   http://www.arduino.cn/thread-42850-1-1.html
    2.结算AHRS姿态   http://www.arduino.cn/thread-42851-1-1.html
    3.姿态数据可视化   http://www.arduino.cn/thread-42852-1-1.html
    4.IMU中断检测   http://www.arduino.cn/thread-42853-1-1.html
    5.神经元与机器学习   http://www.arduino.cn/thread-42854-1-1.html
    如果以上内容对你有帮助,你可以通过打赏支持作者
    跟奈奈大大学习一个
    打赏作者鼓励一下!
    奈何col 发表于 2017-3-15 23:36
    本教程分为五部分:
    1.配置IMU及获取数据   http://www.arduino.cn/thread-42850-1-1.html
    2.结算AHRS姿 ...

    懂了懂了  谢谢!昨晚没有仔细看……
    12下一页
    发新帖
    发表评论
    高级模式  
    您需要登录后才可以回帖 登录 | 立即注册  
    关闭

    推荐主题 上一条 /2 下一条