Applicazioni Arduino con 3D studio Max: come simulare il controllo dei servomotori di un braccio meccanico

Quello che segue è un progetto realizzato con Arduino e prevede l’utilizzo di 3D Studio Max. Il progetto nasce dall’idea di utilizzare un’ applicazione 3D per simulare le modalità secondo le quali è possibile controllare i servomotori di un braccio meccanico con un Wiichuck. La cosa più difficile consiste nel trasferimento dei dati da Arduino al 3D.

Il miglior modo per controllare oggetti in 3D è quello di utilizzare tack view per assegnare un tipo differente di controller alle varie proprietà dell’oggetto che si vuole controllare. Per esempio, se si vogliono avere delle lievi vibrazioni sulla punta delle ali di un uccello, è possibile utilizzare un Noise Controller (Controllo per il rumore). Per questo tipo di configurazione è stato utilizzato, in questo caso, il controller Motion Capture.

Configurazione 3D Studio per Windows

3D Studio può utilizzare differenti input per permettere il motion capture: mouse, tastiera, joystick o MIDI. Ecco quindi il setup per Windows:

    - Arduino utilizza un adattatore per WiiChuck di Todbot e la libreria WiiChuck di Tim Hirzel.
    - I dati vengono inviati all’elaborazione tramite una connessione seriale e tradotti in messaggi MIDI CC utilizzando la libreria proMIDI di Chirstian Riekoff.
    - L’ output MIDI proveniente dall’ elaborazione viene inviato a midiYoke.
    - midiYoke invia i dati ricevuti ad Ableton Live
    - Aberton Live rinvia i messaggi CC midiYoke
    - Utilizzare i controller Float Motion Capture su 3D Studio Max per ruotare gli oggetti secondo la modalità pitch and roll del Wiichuck

Tutto questo può sembrare un tantino complicato, ma 3D Studio non vuole leggere direttamente da midiYoke senza essere passato prima attraverso Ableton Live.

Il lato negativo qui è che i messaggi CC sono di soli 8 bit (128 valori), quindi c’è ancora bisogno di capire come ottenere una risoluzione migliore e gestire i valori negativi.

In ogni modo, è molto interessante il fatto che si possa utilizzare Arduino con ogni tipo di sensore per emettere i propri dati direttamente in 3D Studio Max per realizzare delle motion Capture, ponendo ad esempio dei piccoli accelerometri sulla punta di ogni dito.

Vediamo i codici di testo:

#include "Wire.h"
#include "WiiChuck.h"

WiiChuck chuck = WiiChuck();
int zPress = 0;
int aX, aY, aZ;

// Arrays to store the values and smooth out the output
int rollA[8],pitchA[8],xA[8],yA[8],zA[8];
int i=0;

void setup() {
  Serial.begin(115200);
  chuck.begin();
  chuck.update();
  chuck.calibrateJoy();
}

void loop() {
  chuck.update();
  int roll, pitch, x, y, z, bZ, bC, joyX, joyY;
  // Cycle through arrays and store values
  rollA[i] = (int)chuck.readRoll();
  pitchA[i] = (int)chuck.readPitch();
  xA[i] = (int)chuck.readAccelX();
  yA[i] = (int)chuck.readAccelY();
  zA[i] = (int)chuck.readAccelZ();

  // Smooth values
  for (int j=0;j<8;j++) {
    roll+=rollA[j];
    pitch+=pitchA[j];
    x+=xA[j];
    y+=yA[j];
    z+=zA[j];
  }
  roll=roll/8;
  pitch=pitch/8;
  x=x/8;
  y=y/8;
  z=z/8;

  // Send the values via serial only if Z button is pressed
  if (chuck.zPressed() == 1) {
    if (zPress == 0) {
      zPress = 1;
    }
    Serial.print(roll);
    Serial.print(",");
    Serial.print(pitch);
    Serial.print(",");
    Serial.print(x);
    Serial.print(",");
    Serial.print(y);
    Serial.print(",");
    Serial.print(z);
    Serial.println();
  } else {
    zPress = 0;
  }

  // Increment position in Arrays
  i++;
  if(i==8) {
    i=0;
  }

  delay(20);
}

Processing

int sensorCount = 5;                        // number of values to expect

import processing.serial.*;
Serial myPort;                // The serial port

import promidi.*;
MidiIO midiIO;
MidiOut midiOut;

int BAUDRATE = 115200;
char DELIM = ','; // the delimeter for parsing incoming data

void setup()
{
  size(100,100);
  background(0);
  myPort = new Serial(this, Serial.list()[0], BAUDRATE);
  myPort.clear();

  //get an instance of MidiIO
  midiIO = MidiIO.getInstance(this);
  midiIO.printDevices();
  //open an midiout using the fourth device and the fifth channel
  midiOut = midiIO.getMidiOut(5,4);
}

void draw()
{
  // NOTHING
}
float[] sensorValues = new float[sensorCount];  // array to hold the incoming values

void serialEvent(Serial myPort) {
  // read incoming data until you get a newline:
  String serialString = myPort.readStringUntil('\n');
  // if the read data is a real string, parse it:

  if (serialString != null) {
    // split it into substrings on the DELIM character:
    String[] numbers = split(serialString, DELIM);
    // convert each subastring into an int
    if (numbers.length == sensorCount) {
      for (int i = 0; i < numbers.length; i++) {
        // make sure you're only reading as many numbers as
        // you can fit in the array:
        if (i <= sensorCount) {
          // trim off any whitespace from the substring:
          numbers[i] = trim(numbers[i]);
          sensorValues[i] =  float(numbers[i]);
        }
        // Put the value between 0 & 127
        int val = Math.min(127,Math.abs((int)sensorValues[0]));
        // Sends the value as Controller 10 on the MIDI channel we opened
        midiOut.sendController(
          new Controller(10,val)
        );
        // Problem with the pitch, so -1700, really not accurate ^^
        int val2 = Math.min(127,Math.abs((int)sensorValues[1]-1700));
        midiOut.sendController(
          new Controller(11,val2)
        );
      }
    }
  }
}

La scheda Arduino disponibile da Farnell

Scarica subito una copia gratis

Una risposta

  1. Avatar photo Casciana17 24 Marzo 2011

Scrivi un commento

Seguici anche sul tuo Social Network preferito!

Send this to a friend