Wednesday, October 14, 2009

Lab 3b - Creating virtual environments

Days Three to Seven:
After we took care of the frequency runs, we attempted to create three virtual environments: (1) a virtual wall, (2) a damper, and (3) a mass-spring system. Below, you can see the code we wrote and videos for (1) and (2).

Virtual Wall

// These constants won't change. They're used to give names
// to the pins used:
const int digitalOutPin = 0; // Connect to DIR pin
const int analogInPin = 0; // Connect to PMWM
const int analogOutPin = 5; // Analog output pin that the LED is attached to

int sensorValue = 0; // value read from the pot
int outputValue = 0; // value output to the PWM (analog out)
int designValue = 128;
int measureValue = 127;
int measureoldValue = 127;
int Kd = 0.1;
int Kp = 0.1;
int velocity = 0;

void setup() {
// initialize serial communications at 9600 bps:
Serial.begin(9600);
}

void loop() {
// read the analog in value:
sensorValue = analogRead(analogInPin);
// map it to the range of the analog out:
measureValue = map(sensorValue, 494, 520, 0, 255);
// direction control
digitalWrite(digitalOutPin, HIGH); // set direction to right
// P controller
if (measureValue < outputvalue =" abs" outputvalue =" 0;" sensor = " ); Serial.print(sensorValue); Serial.print(" output = "); Serial.print(outputValue); Serial.print(" measure =" " measureoldvalue="measureValue;">





Damper


// These constants won't change. They're used to give names
// to the pins used:
const int digitalOutPin = 24; // Connect to DIR pin
const int analogInPin = 0; //
const int analogOutPin = 5; // Connect to PWM
const int analogInPin2 = 2; // Vout from hall effect current sensor

int sensorValue = 0; // value read from the pot
int outputValue = 0; // value output to the PWM (analog out)
int designValue = 128;
int sensoroldValue = 0;
int measureValue = 0;
int velocity = 0;
int sensorValue2 = 0;
int Kd = 1;

void setup() {
// initialize serial communications at 9600 bps:
Serial.begin(9600);

}

void loop() {
// read position information:
sensorValue = analogRead(analogInPin);
// read the Vout from current value through Hall effect sensor
sensorValue2 = analogRead(analogInPin2);
// map position to the range of the analog out:
measureValue = map(sensorValue, 494, 520, 0, 255);
// Define direction of output
if (velocity > 0) {
digitalWrite(digitalOutPin, HIGH); // set direction to right
}
else {
digitalWrite(digitalOutPin, LOW);
}
// virtual damper
outputValue = abs(velocity);
analogWrite(analogOutPin, outputValue);
// print the results to the serial monitor:
Serial.print("current = " );
Serial.print(sensorValue2);
Serial.print("\t velocity = ");
Serial.print(velocity);
Serial.print("\t output = ");
Serial.println(outputValue);
velocity = (sensorValue - sensoroldValue) * Kd ;
delay(10);
sensoroldValue=sensorValue;
}






Mass-Spring System

Below is the pseudo code for the mass-spring system.

When the code was implemented in the Arduino, the motor would vibrate violently due to the relatively large time steps (90 m seconds) and the low resolution of the hall effect sensor.


  1. Set virtual mass displacement (d1), velocity (v1), and acceleration (a1) as zero loop
  2. Read Time Stamp(t)
  3. Calculate time difference from last step dt = t – t_old
  4. Read armature position (hall effect sensor) data (d)
  5. Calculate difference of armature position and virtual mass position (d – d1)
  6. Multiply Kd to (d-d1) to find force due to virtual spring (F)
  7. Apply current through motor to represent the force (F) due to virtual spring
  8. Divide virtual mass by the force calculate in (7) to get acceleration of virtual mass (a1)
  9. Integrate virtual mass acceleration to get velocity v1=v1old + a1 * dt
  10. Integrate virtual mass velocity to get displacement d1=d1old + v1 * dt
  11. Set current values as old:
t_old = t
a1old = a1
v1old = v1
d1old = d1
end loop


The video below shows the effect of implementing the virtual mass-spring:



The haptic interface exercise provided us great insight into how to mimic mechanical behaviors while helping us to better understand how to program the Arduino given the motor characteristics we had.

The virtual environment that was the hardest to implement (and the one that we actually did not even end up getting to work) was the mass-spring system mainly due to the fact we had to create for a double integral in the Arduino, which ended up putting us far from the desired result due to the complexity of our coding.

The most satisfying environment to implement, on the other hand, was the damper due to the simplicity of our coding, since it required only one proportional control which was then multiplied by our velocity.

To make the device better, we could have assembled the motor better. This includes, but is not limited to, the way we wound the wires, the orientation of the small magnets, and the spacing about the envelope of motion. If these were assembled better to begin with, we would have had a lot fewer outside sources of error to account for.

No comments:

Post a Comment