2015-01-28 2 views
2

Я пытаюсь создать приложение, которое обнаруживает дорожные шишки или выбоины во время вождения, и я искал возможные решения в google, и я нашел решение, которое использует значения акселерометра для обнаружения дорожных ударов.Обнаружение дорожного удара с использованием Core Motion

Я использовал код по этой ссылке, что хорошо, когда вы нажимаете телефон на ладонь, но не обнаруживаете удары во время вождения автомобиля. iOS: Accurately determining energy of a bump from accelerometer output

Я также нашел алгоритм Z-Diff, который может быть использован, чтобы найти дорожные неровности, объяснение этого алгоритма здесь: http://open-sci.net/wiki/sealappexamplepotholes

Это код я использовал:

ЬурейиХ структуры { double x, y, z; } vec_d3;

#define RECENT_COUNT 10 
#define SMOOTH_IP(x,x_new,fac) x = fac * x + (1. -fac) * x_new 
#define DOUBLE_EMPTY DBL_MAX 

-(void)startTakingMotionValues{ 



[motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) { 


    static vec_d3 smooth = {DOUBLE_EMPTY,0,0}; 
    { 
     if(smooth.x == DOUBLE_EMPTY){ 
      smooth.x=accelerometerData.acceleration.x; 
      smooth.y=accelerometerData.acceleration.y; 
      smooth.z=accelerometerData.acceleration.z; 

      return; 
     } 
     SMOOTH_IP(smooth.x, accelerometerData.acceleration.x, 0.9); 
     SMOOTH_IP(smooth.y, accelerometerData.acceleration.y, 0.9); 
     SMOOTH_IP(smooth.z, accelerometerData.acceleration.z, 0.9); 
    } 

    // keep track of last k smoother acceleration values 
    static vec_d3 recent[RECENT_COUNT]; 
    { 
     static int ptr=0; 
     static BOOL gotEnoughData = NO; 

     recent[ptr]= smooth; 
     ptr++; 
     if(ptr==RECENT_COUNT){ 
      ptr=0; 
      gotEnoughData=YES; 
     } 
     if (!gotEnoughData) { 
      return; 
     } 
    } 
    //get the resultant variation in acceleration over the whole array 
    double variation; 
    { 
     vec_d3 min = smooth,max=smooth; 
     for (int i=0; i< RECENT_COUNT; i++) { 
      min.x = MIN(min.x, recent[i].x); 
      min.y = MIN(min.y, recent[i].y); 
      min.z = MIN(min.z, recent[i].z); 

      max.x = MAX(max.x, recent[i].x); 
      max.y = MAX(max.y, recent[i].y); 
      max.z = MAX(max.z, recent[i].z); 
     } 
     vec_d3 V = (vec_d3) 
     { 
      .x = max.x - min.x, 
      .y = max.y - min.y, 
      .z = max.z - min.z 
     }; 
     variation =sqrt(
         V.x * V.x + 
         V.y * V.y + 
         V.z * V.z 
         ); 
    } 
    //smooth it 
    static double var_smoothed = DOUBLE_EMPTY; 
    { 
     if (var_smoothed == DOUBLE_EMPTY) { 
      var_smoothed = variation; 
      return; 
     } 
     SMOOTH_IP(var_smoothed, variation, 0.9); 
    } 

    // see if it's just passed a peak 
    { 
     static double varSmoothed_last = DOUBLE_EMPTY; 
     if (varSmoothed_last == DOUBLE_EMPTY) { 
      varSmoothed_last=var_smoothed; 
      return; 
     } 
     static double varSmoother_preLast = DOUBLE_EMPTY; 
     if (varSmoother_preLast == DOUBLE_EMPTY) { 
      varSmoother_preLast = varSmoothed_last; 
      varSmoothed_last = var_smoothed; 
      return; 
     } 

#define THRESHOLD_IMPLUSE .40 

     if (varSmoothed_last > varSmoother_preLast && 
      varSmoothed_last > var_smoothed && 
      varSmoothed_last > THRESHOLD_IMPLUSE) { 
      didFindLocation=NO; 
      if (newLocation.speed < 5) { 

      }else{ 
      NSLog(@"varSmoothed_last: @ %f",varSmoothed_last); 
      NSLog(@"varSmoother_preLast : %f",varSmoother_preLast); 
      NSLog(@"var_smoothed : %f",var_smoothed); 

      [self.bumpsData addObject:[NSString stringWithFormat:@"%f",varSmoothed_last]]; 
      [self.bumpsTableView reloadData]; 
      } 

      //[self peakedWithImpulse: varSmoothed_last ]; 

     } 
     varSmoother_preLast = varSmoothed_last; 
     varSmoothed_last = var_smoothed; 
    } 

    }]; 
} 
+0

Вы не задали вопрос. Вы должны быть конкретными относительно своего кода и того, что он делает неправильно. – Wain

+0

@Wain Вопрос очень ясный, я использовал код из ссылки, которую я дал во втором абзаце, и я также упомянул, в чем проблема, которую я получаю. Проблема в том, что код не обнаруживает удары во время вождения, но если вы разбиваете телефон на ладони, он обнаруживает этот удар. –

+1

Вы играли с параметрами - THRESHOLD_IMPLUSE, RECENT_COUNT? Также вы можете изменить частоту дискретизации. Все это должно помочь вам изменить чувствительность (я предполагаю, что код и алгоритм работают правильно) – foundry

ответ

1

Вы должны начать играть с параметрами, чтобы получить представление о том, как алгоритм может быть настроен на различные частоты чувствительности:

#define THRESHOLD_IMPLUSE .40 
#define RECENT_COUNT 10 

Также у вас есть коэффициент сглаживания 0,9 вы могли бы попробуйте уточнить:

SMOOTH_IP(smooth.x, accelerometerData.acceleration.x, 0.9); 

Вы пытаетесь изолировать амплитуду и длину волны, что указывает на дорожный удар. Регулировка RECENT_COUNT или коэффициента сглаживания должна позволить вам снизить чувствительность к высокочастотным ударам. Отрегулируйте THRESHOLD_IMPULSE, вероятно, повлияет на отсечку амплитуды.

Чтобы измерить, как это влияет на результаты, вы также должны разработать метод тестирования и измерения. Запись Некоторые данные дорожных шишек помогут вам понять поведение, которое вы надеетесь обнаружить.

После того как вы поняли алгоритм и настроили его, если он все еще не изолирует ваше движение, вы должны взглянуть на другие алгоритмы в первой из ваших ссылок, понять их каждый отдельно и попробовать добавив их в микс.

Смежные вопросы