Tom Minnich
Published © Apache-2.0

Flightduino 101

A drone project that uses the Neural Pattern Recognition Module and other aspects of the Curie Module to advantage for creating a cool drone

IntermediateFull instructions provided24 hours30,461
Flightduino 101

Things used in this project

Hardware components

Arduino 101
Arduino 101
×1

Software apps and online services

Curie Neurons Arduino Library

Story

Read more

Schematics

Arduino Schematic

to keep the project submission system happy that I have included a schematic :)

Code

FlightDuino

Arduino
First Experiments with CurieNeurons to recognize small 11 by 11 pixel images, import this archived Arduino Sketch and have fun with it.
No preview (download only).

Testing Flightduino with Faded Input Images

Arduino
Import the archive to work with fading the images
No preview (download only).

Faded Image Source

Arduino
I thought you might like to look at the source before downloading the archive
//------------------------------------------------------------------------
// Flightduino is a modification of the CurieNeurons SimpleAcademicScript
// Refer to http://www.general-vision.com/documentation/TM_TestNeurons_SimpleScript.pdf
//
// Test Script to attempt to detect the orientation of a smiley face,
//  for possible use to detect a smiley face drone landing pad
//
//
// -----------------------------------------------------------------------
//
// The patterns are arrays of length LEN composed of identical values VAL
// They basically represent horizontal lines with different heights. This representation
// is easy to comprehend the distance between the learned lines (stored in the memory
// of the committed neurons) and a new input line
//
// In this script, the patterns to recognize are generated programatically to
// surround the learned patterns

#include <CurieNeurons.h>
CurieNeurons hNN;

byte VAL=11;
int neuronsAvailable, neuronsCommitted, neuronSize;
int ncr, dist, cat, aif, nid, nsr;
#define W   0   // white pixel is 0
#define G 127   // gray  pixel is 127
#define B 255   // black pixel is 255
#define LEN 121 // 11x11 pixel smiley face array;
byte pattern[LEN]={W,W,B,B,B,B,B,B,B,W,W,
                   W,B,W,W,W,W,W,W,W,B,W,
                   B,W,W,W,W,W,W,W,W,W,B,
                   B,W,W,B,W,W,W,B,W,W,B,
                   B,W,W,W,W,W,W,W,W,W,B,
                   B,W,W,W,W,B,W,W,W,W,B,
                   B,W,W,W,W,W,W,W,W,W,B,
                   B,W,W,B,W,W,W,B,W,W,B,
                   B,W,W,W,B,B,B,W,W,W,B,
                   W,B,W,W,W,W,W,W,W,B,W,
                   W,W,B,B,B,B,B,B,B,W,W}; // values must range between 0-255.
                   
byte pattern_t45[LEN]={W,W,G,B,G,G,G,B,G,W,W, // smiley face twisted 45 degrees counter clockwise
                       W,G,B,G,W,W,W,G,B,G,W, // gray for an uncertain half and half pixel
                       G,B,G,W,W,B,W,W,G,B,G,
                       B,G,W,W,W,W,W,W,W,G,B,
                       G,W,W,W,W,W,W,W,W,W,G,
                       G,W,B,W,W,B,W,W,B,W,G,
                       G,W,W,W,W,W,W,W,G,W,G,
                       B,G,W,W,W,W,W,B,G,G,B,
                       G,B,G,W,W,B,G,G,G,B,G,
                       W,G,B,G,W,W,W,G,B,G,W,
                       W,W,G,B,G,G,G,B,G,W,W}; // values must range between 0-255.
byte pattern_t90[LEN]; // smiley face twisted 90 degrees counter clockwise
byte pattern_t135[LEN]; // smiley face twisted 135 degrees counter clockwise
byte pattern_t180[LEN]; // smiley face twisted 180 degrees counter clockwise
byte pattern_t225[LEN]; // smiley face twisted 225 degrees counter clockwise
byte pattern_t270[LEN]; // smiley face twisted 270 degrees counter clockwise
byte pattern_t315[LEN]; // smiley face twisted 270 degrees counter clockwise                        
byte test_pattern[LEN];                       

#define K 3
int dists[K], cats[K], nids[K];
void fade(byte * src_ptr, byte * dst_ptr, int percent){ // percent should be 0 to 100
  int i,j;
  int temp_pixel;
  for(i=0;i<11;i++){
    for(j=0;j<11;j++){
      temp_pixel = (int) src_ptr[ i + (11*j)];
      if(temp_pixel>G){
        temp_pixel = G + ((temp_pixel-G)*(100-percent))/100;
      }else{
        temp_pixel = G - ((G-temp_pixel)*(100-percent))/100;
      }
      dst_ptr[i + (11*j)] = temp_pixel;
    }
  }  
}
void rotate_ccw_90deg( byte * src_ptr, byte * dst_ptr ){
  int i,j;
  for(i=0;i<11;i++){
    for(j=0;j<11;j++){
      dst_ptr[j + 11*(10-i)] = src_ptr[ i + (11*j)];
    }
  }
}
void setup() {
  Serial.begin(9600);
  while (!Serial);    // wait for the serial port to open

  Serial.println("Welcome to the Flightduino Test Code");

  // Setup the arrays for smiley faces in various orientations
  
  rotate_ccw_90deg(pattern,pattern_t90); // twist pattern 90 deg ccw and store in pattern_t90
  rotate_ccw_90deg(pattern_t90,pattern_t180); // twist pattern_t90 90 deg ccw and store in pattern_t180
  rotate_ccw_90deg(pattern_t180,pattern_t270); // twist pattern_t180 90 deg ccw and store in pattern_t270

  rotate_ccw_90deg(pattern_t45,pattern_t135); // twist pattern_t45 90 deg ccw and store in pattern_t135
  rotate_ccw_90deg(pattern_t135,pattern_t225); // twist pattern_t135 90 deg ccw and store in pattern_t225
  rotate_ccw_90deg(pattern_t225,pattern_t315); // twist pattern_t225 90 deg ccw and store in pattern_t315
  
  // Initialize the neurons
  hNN.begin();
  hNN.getNeuronsInfo( &neuronSize, &neuronsAvailable, &neuronsCommitted);
  Serial.print("Neuron size ="); Serial.println(neuronSize);
  Serial.print("Neurons available ="); Serial.println(neuronsAvailable);
  Serial.print("Neurons committed ="); Serial.println(neuronsCommitted);
  
  //Learn 8 patterns of smiley faces in various orientations
  Serial.print("\nLearning smiley face patterns...");
  hNN.learn(pattern,LEN, 360);
  hNN.learn(pattern_t45,LEN, 45);
  hNN.learn(pattern_t90,LEN, 90);
  hNN.learn(pattern_t135,LEN, 135);
  hNN.learn(pattern_t180,LEN, 180);
  hNN.learn(pattern_t225,LEN, 225);
  hNN.learn(pattern_t270,LEN, 270);
  hNN.learn(pattern_t315,LEN, 315);
  
 #ifdef DISPLAY_COMMITTED 
  // Display the content of the committed neurons
  Serial.print("\nDisplay the committed neurons, count="); Serial.print(neuronsCommitted);
  byte model[neuronSize];
  for (int i=1; i<=neuronsCommitted; i++)
  {  
      hNN.readNeuron(i, &ncr, model, &aif, &cat);
      Serial.print("\nneuron "); Serial.print(i); Serial.print("\tmodel=");
      for (int k=0; k<LEN; k++) { Serial.print(model[k]); Serial.print(", ");} 
      Serial.print("\tncr="); Serial.print(ncr);  
      Serial.print("\taif="); Serial.print(aif);     
      Serial.print("\tcat="); Serial.print(cat);
  }
 #endif
  int responseNbr;
 #ifdef SANITY_CHECK
  Serial.print("\n\nRecognizing a SMILEY: ");
  // Should be a perfect match!
  responseNbr=hNN.classify(pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 45 degree twisted SMILEY: ");
  responseNbr=hNN.classify(pattern_t45, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 90 degree twisted SMILEY: ");
  // Should be a perfect match!
  responseNbr=hNN.classify(pattern_t90, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 135 degree twisted SMILEY: ");
  responseNbr=hNN.classify(pattern_t135, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 180 degree twisted SMILEY: ");
  // Should be a perfect match!
  responseNbr=hNN.classify(pattern_t180, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 225 degree twisted SMILEY: ");
  responseNbr=hNN.classify(pattern_t225, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 270 degree twisted SMILEY: ");
  // Should be a perfect match!
  responseNbr=hNN.classify(pattern_t270, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 315 degree twisted SMILEY: ");
  responseNbr=hNN.classify(pattern_t315, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
      

  Serial.print("\n\nDone with sanity checking perfect data ");
#endif
// Where noise injected testing will go

  Serial.print("\n\nRecognizing a 0 percent faded SMILEY: ");
  fade(pattern, test_pattern, 0);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 2 percent faded SMILEY: ");
  fade(pattern, test_pattern, 2);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 4 percent faded SMILEY: ");
  fade(pattern, test_pattern, 4);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
      Serial.print("\n\nRecognizing a 6 percent faded SMILEY: ");
  fade(pattern, test_pattern, 6);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 8 percent faded SMILEY: ");
  fade(pattern, test_pattern, 8);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 9 percent faded SMILEY: ");
  fade(pattern, test_pattern, 9);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }          
  Serial.print("\n\nRecognizing a 10 percent faded SMILEY: ");
  fade(pattern, test_pattern, 10);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
            
  Serial.print("\n\n TEST 45 Degree CCW twist SMILEY ");
  Serial.print("\n\nRecognizing a 0 percent faded SMILEY: ");
  fade(pattern_t45, test_pattern, 0);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 2 percent faded SMILEY: ");
  fade(pattern_t45, test_pattern, 2);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 4 percent faded SMILEY: ");
  fade(pattern_t45, test_pattern, 4);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
      Serial.print("\n\nRecognizing a 6 percent faded SMILEY: ");
  fade(pattern_t45, test_pattern, 6);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 8 percent faded SMILEY: ");
  fade(pattern_t45, test_pattern, 8);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 10 percent faded SMILEY: ");
  fade(pattern_t45, test_pattern, 10);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 12 percent faded SMILEY: ");
  fade(pattern_t45, test_pattern, 12);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 14 percent faded SMILEY: ");
  fade(pattern_t45, test_pattern, 14);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 16 percent faded SMILEY: ");
  fade(pattern_t45, test_pattern, 16);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
}

void loop()
{
#ifdef SERIAL_AVAIL  
  if (Serial.available() == 3) 
  {
      VAL = Serial.read() - 48;
      VAL = VAL *10 + Serial.read() - 48;
      Serial.read(); // to read the newline
      for (int i=0; i<LEN; i++) pattern[i]=VAL;     
      Serial.print("\npattern=");
      for (int i=0; i<LEN; i++) { Serial.print(pattern[i]); Serial.print(", ");}
    
      int responseNbr=hNN.classify(pattern, LEN, K, dists, cats, nids);
      for (int i=0; i<responseNbr; i++)
      {
          Serial.print("\nFiring neuron "); Serial.print(nids[i]);
          Serial.print(", Category="); Serial.print(cats[i]);
          Serial.print(", at Distance="); Serial.print(dists[i]);
      }  
      Serial.print("\n\nEdit a value between [10 and 30] as the amplitude of a new pattern + Enter");
   }
#endif   
 }

Credits

Tom Minnich

Tom Minnich

19 projects • 80 followers
Embedded software guy for a long time

Comments