This is the code we showed at Uncraftivism

Dependencies:   mbed

Committer:
jarkman
Date:
Mon Dec 14 08:28:21 2009 +0000
Revision:
2:01115080f6da
Parent:
1:70d90598d2e7

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jarkman 0:57f4fdadc97f 1 #include "stdafx.h"
jarkman 0:57f4fdadc97f 2
jarkman 0:57f4fdadc97f 3 #include "mbed.h"
jarkman 0:57f4fdadc97f 4 #include "Frame.h"
jarkman 0:57f4fdadc97f 5 #include "ServoMinder.h"
jarkman 0:57f4fdadc97f 6 #include "MotionFinder.h"
jarkman 0:57f4fdadc97f 7
jarkman 0:57f4fdadc97f 8
jarkman 0:57f4fdadc97f 9 #include "ServoMinder.h"
jarkman 2:01115080f6da 10 #include "Blinker.h"
jarkman 0:57f4fdadc97f 11
jarkman 0:57f4fdadc97f 12
jarkman 0:57f4fdadc97f 13
jarkman 0:57f4fdadc97f 14 extern Logger pcSerial;
jarkman 2:01115080f6da 15 extern Blinker *blinker;
jarkman 0:57f4fdadc97f 16
jarkman 0:57f4fdadc97f 17 // Motion detection for the mbed
jarkman 0:57f4fdadc97f 18
jarkman 0:57f4fdadc97f 19
jarkman 0:57f4fdadc97f 20 MotionFinder::MotionFinder( ServoMinder *xServoMinder, ServoMinder *yServoMinder )
jarkman 0:57f4fdadc97f 21 {
jarkman 0:57f4fdadc97f 22 m_backgroundFrame = NULL;
jarkman 0:57f4fdadc97f 23 m_resultFrame = NULL;
jarkman 0:57f4fdadc97f 24 m_attentionX = 0.5;
jarkman 0:57f4fdadc97f 25 m_attentionY = 0.5;
jarkman 0:57f4fdadc97f 26
jarkman 0:57f4fdadc97f 27
jarkman 0:57f4fdadc97f 28
jarkman 0:57f4fdadc97f 29 m_xServoMinder = xServoMinder;
jarkman 0:57f4fdadc97f 30 m_yServoMinder = yServoMinder;
jarkman 0:57f4fdadc97f 31
jarkman 1:70d90598d2e7 32
jarkman 1:70d90598d2e7 33
jarkman 2:01115080f6da 34 /*
jarkman 0:57f4fdadc97f 35 m_xServoMinder->moveTo( 1.0 );
jarkman 0:57f4fdadc97f 36 wait( 1 );
jarkman 0:57f4fdadc97f 37 m_xServoMinder->moveTo( 0.0 );
jarkman 0:57f4fdadc97f 38 wait( 1 );
jarkman 0:57f4fdadc97f 39 m_xServoMinder->moveTo( 0.5 );
jarkman 0:57f4fdadc97f 40 wait( 1 );
jarkman 0:57f4fdadc97f 41
jarkman 1:70d90598d2e7 42
jarkman 2:01115080f6da 43 m_yServoMinder->moveTo( 0.7 );
jarkman 0:57f4fdadc97f 44 wait( 1 );
jarkman 0:57f4fdadc97f 45 m_yServoMinder->moveTo( 0.0 );
jarkman 2:01115080f6da 46 wait( 2 );
jarkman 0:57f4fdadc97f 47 m_yServoMinder->moveTo( 0.5 );
jarkman 2:01115080f6da 48 wait( 2 );
jarkman 2:01115080f6da 49 */
jarkman 0:57f4fdadc97f 50 }
jarkman 0:57f4fdadc97f 51
jarkman 0:57f4fdadc97f 52
jarkman 0:57f4fdadc97f 53
jarkman 0:57f4fdadc97f 54 MotionFinder::~MotionFinder()
jarkman 0:57f4fdadc97f 55 {
jarkman 0:57f4fdadc97f 56 if( m_backgroundFrame != NULL )
jarkman 0:57f4fdadc97f 57 Frame::releaseFrame( & m_backgroundFrame );
jarkman 0:57f4fdadc97f 58
jarkman 0:57f4fdadc97f 59 if( m_resultFrame != NULL )
jarkman 0:57f4fdadc97f 60 Frame::releaseFrame( & m_resultFrame );
jarkman 0:57f4fdadc97f 61
jarkman 0:57f4fdadc97f 62 }
jarkman 0:57f4fdadc97f 63
jarkman 0:57f4fdadc97f 64 void MotionFinder::newBackground( Frame *frame )
jarkman 0:57f4fdadc97f 65 {
jarkman 0:57f4fdadc97f 66 Frame::releaseFrame( & m_backgroundFrame );
jarkman 0:57f4fdadc97f 67 return processFrame( frame );
jarkman 0:57f4fdadc97f 68 }
jarkman 0:57f4fdadc97f 69
jarkman 0:57f4fdadc97f 70 void MotionFinder::processFrame( Frame *frame )
jarkman 0:57f4fdadc97f 71 {
jarkman 0:57f4fdadc97f 72 if( frame == NULL || frame->m_bad )
jarkman 0:57f4fdadc97f 73 {
jarkman 0:57f4fdadc97f 74 if( m_resultFrame != NULL )
jarkman 1:70d90598d2e7 75 m_resultFrame->m_bad = false;
jarkman 0:57f4fdadc97f 76 return;
jarkman 0:57f4fdadc97f 77 }
jarkman 0:57f4fdadc97f 78
jarkman 0:57f4fdadc97f 79
jarkman 0:57f4fdadc97f 80 if( m_backgroundFrame == NULL )
jarkman 0:57f4fdadc97f 81 {
jarkman 0:57f4fdadc97f 82 m_backgroundFrame = frame;
jarkman 0:57f4fdadc97f 83
jarkman 0:57f4fdadc97f 84 m_delta = 1 << (m_backgroundFrame->m_bitsPerPixel - 4); // smallest interesting change - make sure this is nonzero for 4-bit iamges!
jarkman 0:57f4fdadc97f 85
jarkman 0:57f4fdadc97f 86 if( m_delta < 2 )
jarkman 0:57f4fdadc97f 87 m_delta = 2;
jarkman 0:57f4fdadc97f 88
jarkman 0:57f4fdadc97f 89 Frame::cloneFrame( &m_resultFrame, m_backgroundFrame );
jarkman 0:57f4fdadc97f 90 m_resultFrame->m_bad = false;
jarkman 0:57f4fdadc97f 91 return;
jarkman 0:57f4fdadc97f 92 }
jarkman 0:57f4fdadc97f 93
jarkman 0:57f4fdadc97f 94 if( frame->m_numPixels != m_backgroundFrame->m_numPixels )
jarkman 0:57f4fdadc97f 95 {
jarkman 0:57f4fdadc97f 96 m_resultFrame->m_bad = false;
jarkman 0:57f4fdadc97f 97 return;
jarkman 0:57f4fdadc97f 98 }
jarkman 0:57f4fdadc97f 99
jarkman 0:57f4fdadc97f 100
jarkman 0:57f4fdadc97f 101 uint32_t sumX = 0;
jarkman 0:57f4fdadc97f 102 uint32_t sumY = 0;
jarkman 0:57f4fdadc97f 103 uint32_t sumN = 0;
jarkman 0:57f4fdadc97f 104 uint16_t x = 0, y = 0;
jarkman 0:57f4fdadc97f 105
jarkman 0:57f4fdadc97f 106 for( uint32_t i = 0; i < frame->m_numPixels; i += 1 )
jarkman 0:57f4fdadc97f 107 {
jarkman 0:57f4fdadc97f 108 x ++;
jarkman 0:57f4fdadc97f 109 if( x >= frame->m_width )
jarkman 0:57f4fdadc97f 110 {
jarkman 0:57f4fdadc97f 111 y++;
jarkman 0:57f4fdadc97f 112 x = 0;
jarkman 0:57f4fdadc97f 113 }
jarkman 0:57f4fdadc97f 114
jarkman 0:57f4fdadc97f 115 uint16_t pb = m_backgroundFrame->getPixel( i );
jarkman 0:57f4fdadc97f 116 uint16_t pf = frame->getPixel( i );
jarkman 0:57f4fdadc97f 117
jarkman 0:57f4fdadc97f 118 if( ( pf > pb && pf - pb > m_delta ) || ( pf < pb && pb - pf > m_delta ))
jarkman 0:57f4fdadc97f 119 {
jarkman 0:57f4fdadc97f 120 // different from background
jarkman 0:57f4fdadc97f 121 m_resultFrame->setPixel( i, pf );
jarkman 0:57f4fdadc97f 122 sumX += x;
jarkman 0:57f4fdadc97f 123 sumY += y;
jarkman 0:57f4fdadc97f 124 sumN ++;
jarkman 0:57f4fdadc97f 125
jarkman 0:57f4fdadc97f 126 }
jarkman 0:57f4fdadc97f 127 else
jarkman 0:57f4fdadc97f 128 {
jarkman 0:57f4fdadc97f 129 // same-ish as background
jarkman 0:57f4fdadc97f 130 m_resultFrame->setPixel( i, 0 );
jarkman 0:57f4fdadc97f 131
jarkman 0:57f4fdadc97f 132
jarkman 0:57f4fdadc97f 133 }
jarkman 0:57f4fdadc97f 134
jarkman 0:57f4fdadc97f 135 //and make the background a little bit more like this pixel, to adjust to slow changes in lighting
jarkman 0:57f4fdadc97f 136 if( pf > pb )
jarkman 0:57f4fdadc97f 137 m_backgroundFrame->setPixel( i, pb +1 );
jarkman 0:57f4fdadc97f 138
jarkman 0:57f4fdadc97f 139 if( pf < pb )
jarkman 0:57f4fdadc97f 140 m_backgroundFrame->setPixel( i, pb - 1 );
jarkman 0:57f4fdadc97f 141
jarkman 0:57f4fdadc97f 142 }
jarkman 0:57f4fdadc97f 143
jarkman 0:57f4fdadc97f 144 uint32_t cogX = 0;
jarkman 0:57f4fdadc97f 145 uint32_t cogY = 0;
jarkman 0:57f4fdadc97f 146
jarkman 0:57f4fdadc97f 147 if( frame->m_numPixels < 1 )
jarkman 0:57f4fdadc97f 148 frame->m_numPixels = 1;
jarkman 0:57f4fdadc97f 149
jarkman 0:57f4fdadc97f 150 uint32_t percentage = (sumN * 100) / frame->m_numPixels;
jarkman 0:57f4fdadc97f 151
jarkman 0:57f4fdadc97f 152 pcSerial.printf("\r\n%d percent changed pixels\r\n", (int) percentage);
jarkman 0:57f4fdadc97f 153
jarkman 0:57f4fdadc97f 154 if( percentage < 3 ) // no real target, no COG
jarkman 0:57f4fdadc97f 155 {
jarkman 0:57f4fdadc97f 156 pcSerial.printf("No COG\r\n");
jarkman 2:01115080f6da 157
jarkman 2:01115080f6da 158 m_xServoMinder->setSpeed( 0.02 );
jarkman 2:01115080f6da 159 m_yServoMinder->setSpeed( 0.02 );
jarkman 2:01115080f6da 160
jarkman 2:01115080f6da 161 blinker->setBoredom( 1 );
jarkman 0:57f4fdadc97f 162
jarkman 2:01115080f6da 163 m_attentionX = m_attentionX + (((0.5 - m_attentionX))/20);
jarkman 2:01115080f6da 164 m_attentionY = m_attentionY + (((0.7 - m_attentionY))/20);
jarkman 0:57f4fdadc97f 165 // could implement some looking-around in this state
jarkman 2:01115080f6da 166
jarkman 2:01115080f6da 167
jarkman 0:57f4fdadc97f 168
jarkman 0:57f4fdadc97f 169 }
jarkman 0:57f4fdadc97f 170 else if( sumN > 0 )
jarkman 0:57f4fdadc97f 171 {
jarkman 2:01115080f6da 172 m_xServoMinder->setSpeed( 0.25 );
jarkman 2:01115080f6da 173 m_yServoMinder->setSpeed( 0.25 );
jarkman 2:01115080f6da 174
jarkman 0:57f4fdadc97f 175 cogX = sumX / sumN;
jarkman 0:57f4fdadc97f 176 cogY = sumY / sumN;
jarkman 0:57f4fdadc97f 177
jarkman 0:57f4fdadc97f 178 m_attentionX = ((float)cogX / frame->m_width);
jarkman 0:57f4fdadc97f 179 m_attentionY = ((float)cogY / frame->m_width); // use the larger dimension so x & y get the same scaling
jarkman 0:57f4fdadc97f 180
jarkman 2:01115080f6da 181 //blinker->setBoredom( 0 );
jarkman 2:01115080f6da 182 float boredom = (2*percentage)/100.0;
jarkman 2:01115080f6da 183 if(boredom > 1) boredom = 1;
jarkman 2:01115080f6da 184 blinker->setBoredom( boredom );
jarkman 2:01115080f6da 185
jarkman 2:01115080f6da 186
jarkman 0:57f4fdadc97f 187 pcSerial.printf("COG is %d, %d\r\n", (int) cogX, (int) cogY);
jarkman 0:57f4fdadc97f 188
jarkman 0:57f4fdadc97f 189 }
jarkman 0:57f4fdadc97f 190
jarkman 0:57f4fdadc97f 191 m_xServoMinder->moveTo( 1 - m_attentionX );
jarkman 1:70d90598d2e7 192 m_yServoMinder->moveTo( m_attentionY );
jarkman 0:57f4fdadc97f 193
jarkman 0:57f4fdadc97f 194
jarkman 0:57f4fdadc97f 195 Frame::releaseFrame( &frame );
jarkman 0:57f4fdadc97f 196
jarkman 0:57f4fdadc97f 197 m_resultFrame->m_bad = false;
jarkman 0:57f4fdadc97f 198 return;
jarkman 0:57f4fdadc97f 199 }
jarkman 0:57f4fdadc97f 200
jarkman 0:57f4fdadc97f 201
jarkman 0:57f4fdadc97f 202