Posts mit dem Label data analysis werden angezeigt. Alle Posts anzeigen
Posts mit dem Label data analysis werden angezeigt. Alle Posts anzeigen

Samstag, 27. Oktober 2012

Some Data Visualization

My friend Johanna asked me to help her figure out how to visualize some data she was working with.

(Maybe I can get her to update this blog with some actual information on the Data. My Estonian is about as good as my Esperanto or my Inuit, so I know what the labels on the data say, but well. Not what they mean)

She gave me a list of buildings of a district of Talinn. Each building had two datapoints: a) it was classified according to some (to me completely mystical) Estonian system and b) the year it was built in. My first thought was to just to give each classification a value and create a scatter plot:


This initially seemed quite useful. You can see which classifications concern newer buildings, which ones concern older buildings. You can see that very few - well actually, no buildings at all where built after 1940 and before 1945. However, I did not feel like one sees the entire picture. So I decided to add some jitter. Once I saw the result, I decided to add a whole lot more jitter. This is the graph I came up with:


Here we can see a whole lot more detail. For example the third, fourth and fifth category from the top looked fairly similar around the year 200 in the first graph. Here we see that there is actually a lot more going on. I still was not quite satisfied, so I considered it a programming challange and tried to see what I could come up with using processing.


I would have never anticipated the huge spike in the first classification just by looking at the chart I had previously made. I'm not quite sure if the mirrored thing is so smart, as it might make the differences between a large and a small number of occurrences appear to be smaller then it is... still, I think its a pretty graph.

Here is (some of) the code I used:
("some of" because estonian seems to break snippler which I use for the code formatting)


Finally, this is what happened, when i did not use pushMatrix() and popMatrix() correctly. I think its quite a beautiful result:




Sonntag, 2. Januar 2011

Motion Capturing with Stretch Sensor

I have not posted in a while here... anyway ... I wrote a report to wrap up everything I have done so far before I go off to Canada... I'll upload it somewhere... this here is the part that is probably most interesting for most people... (its not 1 to 1 the way it'll be in my final report, but close enough...)



Stretch Sensors

The stretch sensors I use are made of conductive plastic material which changes its resistance depending on the amount it is stretched. This material is produced by the American company Images and can be bought directly at their webshop or  at shops such as the RobotShop. The material is approximately 2mm in diameter and can be stretched up to 175%. 

Basically I want to capture body movement, which is induced by muscles. Muscles are linear actuators; the only movement which they can perform is expanding or contracting. This implies, that all movements of the body are measurable in terms of contracting (flexing) or expanding (relaxing) of the muscle by stretch sensors.

Angular Movement (Elbow and Shoulder)

           The axis of rotation is inaccessible which would be a problem for most sensor types. However, the fact that the attachment points vary in distance  to each other (when measured around the elbow as seen in the following picture) is actually of benefit for this sensor. In the elbow the Triceps Brachii is the main muscle controlling the elbows motion and takes advantage of this very principle. The stretch sensor basically copies the Triceps motion. The following two graphs compare the stretch sensor with the flex sensor. You can see that the flex sensor requires a sliding attachment while the stretch sensor can be permanently attached due to its elasticity.



Capturing angular movement with flex and stretch sensor (sharp angle, Tricaps Brachii relaxed)


Capturing angular movement with flex and stretch sensor (blunt angle, Triceps Brachii flexed)



            Rotational Movement (Rotation of upper and lower arm)

The fact that the rotational axis is not accessible is of no relevance to the stretch sensor as we are not interested in measuring the actual rotation. What is measured is the distance between the two attachment points. From this one can then make inferences on the rotation of the arm. This method works analogue to the Pronator Teres in the lower arm, which by flexing or relaxing dictates the rotation of the wrist. The following two graphs demonstrate how rotating the arm is merely a change in distance between two attachment points.

 Measuring rotation with stretch sensor (Pronator Teres flexed)


 Measuring rotation with stretch sensor (Pronator Teres relaxed)

Working model of ShadowCoat using stretch sensors sewn to long sleeved t-shirt

Signal Processing


One of the drawbacks of using stretch sensors as opposed to using potentiometers is that stretch sensors have an ill defined output. The output is neither logarithmic nor exponential nor straight and is additionally dependent not only on the sensors current state, but also on its previous state. The next image displays the relationship between stretch and signal level. Note how the output is almost linear between 125% stretch and 156.25% stretch. Also note how sensitive the sensor is below 112.5% stretch (sorry for the hard-to-read graph, ill get a nicer version online eventually).


 Change of signal strength depending on stretch of sensor

The next image displays sensor output over time. The x axis is the magnitude of the signal and the y axis displays its change over time. What is displayed is a sensor in relaxed state which is then abruptly pulled to 175% of its original length and the abruptly released again. Note the spikes after stretching and while releasing the tension of the sensor. Interesting is also the gradual decline of the signal after relaxation of the sensor. In this example the sensor has been previously already stretched several times. Therefore the initial signal is already higher than the initial signal at the start of experimentation. I did not establish the time it takes for the sensor to return to baseline state, but it takes quite some time.


 Change of signal over time when stretched to 175% and released again

While the sensor is mechanically ideal for the application, the problems just discussed show that there is much need for signal optimization. This can be done on the software and hardware end of things.

Hardware aspects of signal optimizing:


The signal can be optimized by using two counteracting sensors. These should be arranged in such a form, that they are always in opposite phase to each other. The following graphs demonstrate how this can be achieved.



 Measuring rotation with two counteracting stretch sensors (Pronator Teres stretched)


Measuring rotation with two counteracting stretch sensors (Pronator Teres relaxed)


Capturing angular movement with two counteracting stretch sensors (sharp angle)

Capturing angular movement with two counteracting stretch sensors (blunt angle)

In all examples, one sensor is stretched while the other sensor is relaxes. The two sensor can never both be relaxed or stretched at the same time; they counteract eachother. By adding the two signals together it is possible to improve the sensor.

Software aspects of Signal Optimizing



The signal of one of the sensors needs to be inverted, allowing for both readings to be used together. If averaged there are several benefits. First of all, the new output is now closer to a linear function – in practice this deviation from linear relationship has proven to be neglectable; the output can be considered approximately linear.


Change of signal strength of  two counteracting stretch sensors and the average signal depending on stretch

If one is mainly interested in amplitude of the signal, two counteracting sensors can be used in a way to maximize the output at the cost of linearity. The fact that signal A is more sensitive below 137.5% and signal B is more sensitive above 137.5% can be taking advantage of by simply creating a threshold value for assigning which sensors readings will be used. One could also use a soft threshold, starting out by using 100% of sensor A’s signal and then gradually adding sensor B’s signal while decreasing sensor A’s contribution to the final signal. If there is little stretch, one would rely mainly on sensor A, while with strong stretch sensor B would be the dominant. This takes advantage of the most sensitive data-range of both sensors.

Noise Reduction

Using two discreet signals and taking the average can also be beneficial in reducing the noise level of the signal. However the noise does not necessarily cancel out, which requires for additional noise reduction measures. One way of achieving this is simply averaging over time, one could for example wait till 10 readings have accumulated. Each outputted value from then on is the average of its 10 predecessors. This method however has the drawback that there is a noticeable time delay and that the response is sluggish.
            The time delay and the sluggish response can be reduced be dynamic averaging, for example by using an algorithm which outputs the average of the last 5 outputs together with the newest 5 inputs. This dynamic averaging could be considered as a very crude low pass filtering method. A low pass filter does exactly what it says: It allows low frequencies to pass, while blocking high frequency signals. Here are algorithm of two variants of a low pass filter which have proven useful:

float alpha = 0.8;
float rawSignal = sensorInput;
float oldCeanSignal;
float cleanSignal;

void loop()
{
oldCleanSignal = cleanSignal;
cleanSignal = alpha * oldRawSignal + (1 - alpha) * rawSignal;
}

(Rumour has it, that this is what apple uses for cleaning up the output of the gyros in its iPhones etc.)
OR
float alpha = 0.35;
float rawSignal = sensorInput;
float oldCleanSignal;
float cleanSignal;

void loop()
{
oldRawSignal = cleanSignal;
cleanSignal = oldCleanSignal + (alpha * (rawSignal - oldCleanSignal));
}

(I got this code snippet from Jeff Rowberg who is creating another awesome input tool)

Alpha is a value which decides upon how strong the filter should work on the signal, it has slightly different functions in both algorithms. sensorInput is the voltage reading of the stretch sensor. rawSignal is a variables for storing these voltage readings and cleanSignal is the filtered signal. oldCleanSignal is a variable for storing the cleanSignal of the last iteration.


Artifact Reduction.

As can be seen in figure 12 the release of the stretch sensors signal is very slow and only reaches zero after an extended period of time. Therefore the output at zero stretch (sensor stretched to 100%) can change over time. This effect is reduced because the opposing sensor at 175% stretch has a constent output, however it is only reduced by a factor of 0.5, in other words it still represents a major problem.
            This problem can be solved by regular auto-calibrations. The measured voltage needs to be scaled to a sensible output (ideally to degrees which correspond with the actual degrees of movement.) During this process the program can constantly update maximum and minimum output values, thus allowing for a signal minimum and maximum which is not fixed. To avoid glitches in this autocalibration (such as a spike changing the maximum to something unnaturally high, thus distorting the scale) it may make sense to periodically reset the minimum and maximum output to its average value. A possible algorithm for doing this in Processing can be found below

//calibrating & converting to correct values
   //setting maximas (RAW values are the input signal, HIGH and LOW values are //maximas and minimas used to outocalibrate

    if (wristRotateARAW > wristRotateAHIGH){
      wristRotateAHIGH = wristRotateARAW;
    }
    if (wristRotateBRAW > wristRotateBHIGH){
      wristRotateBHIGH = wristRotateBRAW;
    }
    if (elbowAngleRAW > elbowAngleHIGH){
      elbowAngleHIGH = elbowAngleRAW;
    }
    //setting minimas
    if (wristRotateARAW < wristRotateALOW){
      wristRotateALOW = wristRotateARAW;
    }
    if (wristRotateBRAW < wristRotateBLOW){
      wristRotateBLOW = wristRotateBRAW;
    }
    if (elbowAngleRAW < elbowAngleLOW){
      elbowAngleLOW = elbowAngleRAW;
    }
  
// remapping to degrees
    wristRotateA = map(x, wristRotateALOW, wristRotateAHIGH, 0, 180);
    wristRotateB = map(y, wristRotateBLOW, wristRotateBHIGH, 0, 180);
    elbowAngle   = map(z, elbowAngleLOW, elbowAngleHIGH, 0, 180);
   

//creating compound variables
   
    wristRotate = (950 - wristRotateA +  wristRotateB )/ 2;

//reset scaling at mouseclick (this could also be done automatically at descreet time //intervalls, but then one would have to be more carefull with the values you assign //then I am in this peace of code. I still need to work on this.

if (mousePressed == true) {
 
   wristRotateALOW = 10000;        // minimum measured value
   wristRotateBLOW = 10000;        // minimum measured value
   elbowAngleLOW = 10000;          // minimum measured value

   wristRotateAHIGH = -10000;       // maximum measured value
   wristRotateBHIGH = -10000;       // maximum measured value
   elbowAngleHIGH = -10000;         // maximum measured value;

  }


-----------------------------------------------------------
 Anyway - thats it for now. I'll upload my full (preliminary) report soon-ish

p.

Freitag, 15. Oktober 2010

Getting better aquainted with the Stretch Sensors

As mentioned in a previous post, I now have a stretch sensor by Images in my possession. Though I was first a bit skeptical I am beginning to see more and more ways of using this. I sort of had a hunch that the relationship between stretch and resistance might not be linear (yeah admitted, nothing strange in that, I would be more surprised *where* there a linear relationship.)

I am a visual person and I need to see things to understand them, so I made these graphs:

Stretched to 125 % of original length.

Stretched to 150 %

Stretched to 175 %

Stretched to 112.5 %, 125 %, 137.5 %, 150 %, 162,5 %, and 175%

Stretched with incrementions of 6.25 %

Due to the fact that I am lazy the graphs might be a bit confusing to read. The x-axis represents time and the white vertical lines represent seconds (I just double checked my math and the white lines are more like half seconds - maybe I will redo these if I get around to it. However you still get the generally picture). The y-axis measure the change in resistance. The light gray area is the resistance of the sensor. I did not add units, as the interesting part is the relative change and that is all I measured. 
The fact that the signal is non-linear can, with some tinkering, be used as a bonus. The resolution in the first couple percent of stretch is quite high - so if I where to use two stretch sensors simultaneously but in opposite phase (if one is loose, the other one is stretched) I should be able to maximize the resolution available :-)

Freitag, 8. Oktober 2010

off topic --> Skiing & The Acceleration of Time

Another thing I was looking into was sports. I just have this vague memory of seeing some Austrian guy winning the slalom world championship in the 50's even though he had to track back for a second as he almost missed a gate.

As we all know, that does not really happen anymore today. (Missing gates: yes. Missing gates, backtracking and winning: nope.)

So I got myself the finishing times of the best 6 skiers in all World Championship and Olympic slalom events. Then I plotted some graphs. I found the results quite fascinating. I will show all graphs first with regular scales and then with logarithmic scales.

  • Graph one shows the difference in time between first and second
  • Graph two shows the difference in time between the first and the average of the first 6 (I included the first in this average, which is a bit silly, I just realized, but oh well...)
  • Graph three shows the difference between the first and the sixth person to cross the finish





Whats really interesting here, IMHO is that these graphs don't look like some random development, governed by society and technological development. These graphs look more like something following a natural law.

I find the level of correlation quite spooky, to be honest. Take a look at these logarithmic charts...









The numbers in the graph is difference in time, measured in seconds.

Anyway. I would love to hear what other people have to say to the things I'm posting. I know people are reading this, and there is a comment function. Feel free to use it :-)