Как заставить обработку использовать часть массива - PullRequest
1 голос
/ 05 апреля 2020

Программное обеспечение для анализа в реальном времени чипа акселерометра. Однако он не будет создавать график с использованием компонентов массива. Когда я заменяю часть dat [0/1/2] в void drawAxes действительным числом, создается график.

Есть ли способ заставить массив dat [] работать в этой системе, или какие альтернативы я могу использовать? dat [] * 100 просто для увеличения введенного значения.

//Accelerometer graphing programme
//Author: Owain L. Evans, owainlevans@outlook.com
//Takes data from Arduino and produces a 3-Dimensional visualisation


import processing.serial.*;

Serial myPort; //Serial Port
String DataLine; //Input from serial port

float[] dat;

PVector a = new PVector(100, 50, 20);

void setup()
  {
  size(1024, 720, P3D);
  strokeWeight(3);

  dat = new float[3];

  String portName = Serial.list()[0];
  myPort = new Serial(this, portName, 9600);
}

void draw() {
  if (myPort.available() > 0)
    {DataLine = myPort.readStringUntil('\n');
    }
  if (DataLine != null) {
  println(DataLine);
  float dat[] = float(split(DataLine, ","));  //parse comma-separated number string into numbers
  println(dat);
  println();
  }
  background(250);
  drawAxes(dat[0]*100, dat[1]*100, dat[2]*100);  //draw original coordinate system
  translate(width * 0.5, height * 0.5, 0);
  rotateX(map(mouseY,0,height,-PI,PI));
  rotateY(map(mouseX,0,width,-PI,PI));

  drawAxes(dat[0]*100, dat[1]*100, dat[2]*100);

  pushMatrix();
  translate(a.x, a.y, a.z);  //isolate coordinate system and draw translated A point
  popMatrix();
}

void drawAxes(float x, float y, float z) {
  //X - red
  stroke(192, 0, 0);  
  line( 0, 0, 0, x, 0, 0);
  //Y - green
  stroke(0, 192, 0);
  line(0, 0, 0, 0, y, 0);
  //Z - blue
  stroke(0, 0, 192);
  line(0, 0, 0, 0, 0, z);
}

1 Ответ

0 голосов
/ 05 апреля 2020

Трудно сказать, что происходит с массивом, но вы можете добавить параметры к drawAxes(), которые уберут жесткую связь с dat и сделают его многократно используемым для других эскизов:

void drawAxes(float x, float y, float z) {
  //X - red
  stroke(192, 0, 0);  
  line( 0, 0, 0, x, 0, 0);
  //Y - green
  stroke(0, 192, 0);
  line(0, 0, 0, 0, y, 0);
  //Z - blue
  stroke(0, 0, 192);
  line(0, 0, 0, 0, 0, z);
}

(например, drawAxes(dat[0] * 100, dat[1] * 100, dat[2] * 100);)

Обновление Я понимаю, что вы имеете в виду: вы хотели бы построить график входящих данных и графика.

Проблема в том, что в данный момент вы храните только один образец, который постоянно обновляется.

Чтобы построить график с несколькими значениями, вам необходимо:

  1. создать массив для хранения нескольких выборок
  2. обновить массив (сдвигать старые значения по мере поступления новых)
  3. перебирать массив и отображать каждое значение

Шаг 1: создать массив [n-samples][3] 2D для хранения входящих данных. Для аргументации давайте сохраним историю из 30 сэмплов:

int sampleDimensions = 3;
// how many samples to record
int numSamples = 30;
// where to store the data
float[][] samples = new float[numSamples][sampleDimensions];

Шаг 2: Обновление сэмплов (смещение старых, добавление новых данных):

// read a new sample x,y,z entry and append it
void updateSamples(float x, float y, float z) {
  // shift oldest samples by 1: count backwards from oldest sample to 2nd sample
  for (int i = numSamples - 1; i > 0; i--) {
    // copy previous sample data: offsetting old data by 1
    samples[i][0] = samples[i-1][0];
    samples[i][1] = samples[i-1][1];
    samples[i][2] = samples[i-1][2];
  }
  // add newest entry as the first sample (replacing old data)
  samples[0][0] = x;
  samples[0][1] = y;
  samples[0][2] = z;
}

Шаг 3 Итерация по данным и графику:

// render samples on screen with the option to scale the data
void drawSamples(float scale) {
  for (int i = 0 ; i < numSamples; i++){
    drawAxes(samples[i][0] * scale, samples[i][1] * scale, samples[i][2] * scale);
  }
}

Имейте в виду, что это не очень эффективно с точки зрения рендеринга, однако для 30 сэмплов все должно быть хорошо. В конце концов важна разборчивость стиля визуализации.

Если вы хотите упростить визуализацию, вы можете просто визуализировать строку:

void drawSamples(float scale) {
  beginShape();
  for (int i = 0 ; i < numSamples; i++){
    vertex(samples[i][0] * scale, samples[i][1] * scale, samples[i][2] * scale);
  }
  endShape();
}

Соединение всего этого вместе :

import processing.serial.*;

Serial myPort; //Serial Port
String dataLine; //Input from serial port

PVector a = new PVector(100, 50, 20);

int sampleDimensions = 3;
// how many samples to record
int numSamples = 30;
// where to store the data
float[][] samples = new float[numSamples][sampleDimensions];

// stores a single data sample from serial
float[] sample = new float[sampleDimensions]; 
// how much to scale data for visualisation
float sampleRenderScale = 100;

void setup() {
  size(1024, 720, P3D);
  strokeWeight(3);
  noFill();
  // try to open serial connection: display error otherwise (port missing, or busy (already open in Serial Monitor, etc.))
  try {
    String portName = Serial.list()[0];
    myPort = new Serial(this, portName, 9600);
  }catch(Exception e) {
    println("error openin serial port: " + Serial.list()[0]);
    e.printStackTrace();
  }

}

void draw() {
  if(myPort != null){
    if (myPort.available() > 0){
      dataLine = myPort.readStringUntil('\n');

      if (dataLine != null) {
        println(dataLine);
        sample = float(split(dataLine, ","));  //parse comma-separated number string into numbers
        println(sample);
        if(sample == null || sample.length < 3){
           println("parsed less than the expected 3 values:");
           return;
        }
        println();
        // add new sample to the list of recorded samples
        updateSamples(sample[0], sample[1], sample[2]);
      }
    }
  }


  background(250);

  drawAxes(sample[0] * sampleRenderScale, sample[1] * sampleRenderScale, sample[2] * sampleRenderScale);  //draw original coordinate system

  translate(width * 0.5, height * 0.5, 0);
  rotateX(map(mouseY, 0, height, -PI, PI));
  rotateY(map(mouseX, 0, width, -PI, PI));

  drawAxes(sample[0] * sampleRenderScale, sample[1] * sampleRenderScale, sample[2] * sampleRenderScale);
  // draw recorded samples
  drawSamples(sampleRenderScale);

  pushMatrix();
  translate(a.x, a.y, a.z);  //isolate coordinate system and draw translated A point
  popMatrix();
}

// read a new sample x,y,z entry and append it
void updateSamples(float x, float y, float z) {
  // shift oldest samples by 1: count backwards from oldest sample to 2nd sample
  for (int i = numSamples - 1; i > 0; i--) {
    // copy previous sample data: offsetting old data by 1
    samples[i][0] = samples[i-1][0];
    samples[i][1] = samples[i-1][1];
    samples[i][2] = samples[i-1][2];
  }
  // add newest entry as the first sample (replacing old data)
  samples[0][0] = x;
  samples[0][1] = y;
  samples[0][2] = z;
}

// render samples on screen with the option to scale the data
void drawSamples(float scale) {
  beginShape();
  for (int i = 0 ; i < numSamples; i++){
    vertex(samples[i][0] * scale, samples[i][1] * scale, samples[i][2] * scale);
  }
  endShape();
}

void drawAxes(float x, float y, float z) {
  //X - red
  stroke(192, 0, 0); 
  line( 0, 0, 0, x, 0, 0); 
  //Y - green
  stroke(0, 192, 0); 
  line(0, 0, 0, 0, y, 0); 
  //Z - blue
  stroke(0, 0, 192); 
  line(0, 0, 0, 0, 0, z);
}

Обратите внимание на некоторые изменения:

  • DataLine переименован в dataLine (согласно Java Соглашения об именах )
  • обычно переименовывают переменные, чтобы легко понять, что они / делают, и отформатировать код, чтобы было легче читать
  • ошибка обработки последовательного порта. Вы уже сделали обработку ошибок для входящих данных, и это здорово.

Идея состоит в том, чтобы вырабатывать хорошие привычки по мере продвижения.

Если у вас есть время для изучения других языков, я рекомендую Python и несколько модулей, потенциально для того, чтобы начать кластеризацию / классификацию данных датчика, если это представляет интерес:

  • pyserial для последовательной связи
  • SciPy : numpy для быстрой обработки массива, matplotlib для построения графиков и sklearn для классификации / кластеризации / et c.
...