Пример #1
0
void light_led_number (int number) {
  static int done = 0;
  if (done == 0) {
    HAL_Init();

    BSP_LED_Init(LED3);
    BSP_LED_Init(LED4);
    BSP_LED_Init(LED5);
    BSP_LED_Init(LED6);
    BSP_LED_Init(LED7);
    BSP_LED_Init(LED8);
    BSP_LED_Init(LED9);
    BSP_LED_Init(LED10);
    done++;
  }
  BSP_LED_Off(LED3);
  BSP_LED_Off(LED4);
  BSP_LED_Off(LED5);
  BSP_LED_Off(LED6);
  BSP_LED_Off(LED7);
  BSP_LED_Off(LED8);
  BSP_LED_Off(LED9);
  BSP_LED_Off(LED10);

  if (number & 0x1)
    BSP_LED_On(LED3);
  if (number & 0x2)
    BSP_LED_On(LED5);
  if (number & 0x4)
    BSP_LED_On(LED7);
  if (number & 0x8)
    BSP_LED_On(LED9);
  if (number & 0x10)
    BSP_LED_ON(LED10);
  if (number & 0x20)
    BSP_LED_ON(LED8);
  if (number & 0x30)
    BSP_LED_ON(LED6);
  if (number & 0x40)
    BSP_LED_ON(LED4);
}
Пример #2
0
void runCalibration2 ( AttitudeSensor* sensor )
{  

  int i ;
  entryCount ++ ;
  if ( entryCount >= SAMPLE_STEP )
    entryCount = 0 ;
  
  if ( entryCount != 0 )
    return ;
  
  if ( sensor->AllReady )
  {
    BSP_LED_ON(LED_R) ;         // 点亮红灯提示
    BSP_LED_OFF (LED_G) ;        // 关绿灯
    BSP_LED_OFF(LED_B) ;         // 关蓝灯              
    return ;
  }
  

  // 读取加速度计的低通+滑动平均滤波+跟随预测值
  int ax, ay, az , mx , my, mz ;
  ax = getAccXSlideAverage(sensor);
  ay = getAccYSlideAverage(sensor);
  az = getAccZSlideAverage(sensor);
  mx = sensor->mx ;
  my = sensor->my ;
  mz = sensor->mz ;  
  
  
  // 更新加速度的历史值队列
  for (i=0;i<N-1;i++)
  {
    recentAx[i] = recentAx[i+1] ;
    recentAy[i] = recentAy[i+1] ;
    recentAz[i] = recentAz[i+1] ;
    recentMx[i] = recentMx[i+1] ;
    recentMy[i] = recentMy[i+1] ;
    recentMz[i] = recentMz[i+1] ;
  }
  recentAx [N-1] = ax ;
  recentAy [N-1] = ay ;
  recentAz [N-1] = az ;
  recentMx [N-1] = mx ;
  recentMy [N-1] = my ;
  recentMz [N-1] = mz ;
  
  
  if ( validSamples < N )
  {
    validSamples ++ ;
    return ;
  }
  
  
  // 找到当前加速度的主轴
  int16_t* recentAp [3] = { recentAx, recentAy, recentAz };
  int16_t  ra [3] = {ax,ay,az} ; 
  int axis = 0 ;
  int16_t max = ra[axis] ;
  if ( max*max < ay*ay )
  {
    axis = 1 ;
    max = ra[axis] ;
  }
  if ( max*max < az*az )
  {
    axis = 2 ;
    max = ra[axis] ;
  }
  
  for ( i=0 ; i<3 ; i++ )
  {
    if ( i == axis )
      continue ;
    
    float temp = (float)ra[i] / ra[axis] ;
    temp *= temp ;
        
    if ( temp > (0.15*0.15) )
    {
        axis = -1 ;
        break ;
    }
  }
  
  
  // 检查主轴的加速度是否趋于平稳
  if (  axis != -1 &&  axis == stableAxis  )
  {
    bool stable = true ;
    int delta = 0 ;
    for ( i=0; i<N; i++ )
    {
      int temp = recentAp[axis][i] - recentAp[axis][0] ;
      if ( temp < 0 )
        temp = -temp ;
      
      if ( temp > deltaThr )
      {
        stable = false ;
        break ;
      }
    }
    
    if ( stable )
      stableCount ++ ;
    else
      stableCount = 0 ;
    
  }
  else
  {
    stableAxis = axis ;
    stableCount = 0 ;    
  }
  
  

  // 如果主轴已经足够平稳,则采纳主轴的值
  if ( stableCount > N )
  {
    int sum = 0 , sumMx=0, sumMy=0, sumMz=0 ;
    int ave , aveMx, aveMy, aveMz ;
    for ( i=0; i<N; i++ )
    {
      sum += recentAp[axis][i] ;
      sumMx += recentMx[i] ;
      sumMy += recentMy[i] ;
      sumMz += recentMz[i] ;
    }
    ave = sum / N ;
    aveMx = sumMx / N ;
    aveMy = sumMy / N ;
    aveMz = sumMz / N ;

    if ( ave > 0 )
    {
      if ( ! sensor->AccMaxReady[axis] )
      {
        sensor->AccMax[axis] = ave ;      
        goodMagSamples [2*axis][0] = aveMx ;
        goodMagSamples [2*axis][1] = aveMy ;
        goodMagSamples [2*axis][2] = aveMz ;

        sensor->AccMaxReady[axis] = true ;
      }
      else
      {
        sensor->AccMax[axis] = ave*2/100 + (int32_t)(sensor->AccMax[axis])*98/100 ;      
        goodMagSamples [2*axis][0] = aveMx*2/100 + (int32_t)(goodMagSamples [2*axis][0])*98/100 ;
        goodMagSamples [2*axis][1] = aveMy*2/100 + (int32_t)(goodMagSamples [2*axis][1])*98/100 ;
        goodMagSamples [2*axis][2] = aveMz*2/100 + (int32_t)(goodMagSamples [2*axis][2])*98/100 ;
        sensor->AccMaxReady[axis] = true ;        
      }      
    }
    else
    {
      if ( ! sensor->AccMinReady[axis] )
      {
        sensor->AccMin[axis] = ave ;      
        goodMagSamples [2*axis+1][0] = aveMx ;
        goodMagSamples [2*axis+1][1] = aveMy ;
        goodMagSamples [2*axis+1][2] = aveMz ;
        sensor->AccMinReady[axis] = true ;
      }
      else
      {
        sensor->AccMin[axis] = ave*2/100 + (int32_t)(sensor->AccMin[axis])*98/100 ;      
        goodMagSamples [2*axis+1][0] = aveMx*2/100 + (int32_t)(goodMagSamples [2*axis+1][0])*98/100 ;
        goodMagSamples [2*axis+1][1] = aveMy*2/100 + (int32_t)(goodMagSamples [2*axis+1][1])*98/100 ;
        goodMagSamples [2*axis+1][2] = aveMz*2/100 + (int32_t)(goodMagSamples [2*axis+1][2])*98/100 ;
        sensor->AccMinReady[axis] = true ;
      }
    }
    
    
    BSP_LED_OFF (LED_G) ;        // 关绿灯
    BSP_LED_ON(LED_B) ;         // 亮蓝灯
  }
  
  //else if ( stableCount > 0 )
  else if ( axis != -1 )
  {
    BSP_LED_ON (LED_G) ;        // 亮绿灯
    BSP_LED_OFF(LED_B) ;         // 关蓝灯
  } 
  else
  {
    BSP_LED_OFF (LED_G) ;        // 关绿灯
    BSP_LED_OFF(LED_B) ;         // 关蓝灯    
  }
    
  
//#define   AccMagCalibrateTogether
#ifndef AccMagCalibrateTogether

  // 如果加速度的三个轴都已校正过,则校正完毕
  if  (  sensor->AccMaxReady[0] && sensor->AccMinReady[0] && 
                  sensor->AccMaxReady[1] && sensor->AccMinReady[1] &&
                  sensor->AccMaxReady[2] && sensor->AccMinReady[2]  )
  {
    // 对各字段赋值
    for ( i=0; i<3; i++ )
    {
      calibrateParam.data.info.aMax[i] = sensor->AccMax[i] ;
      calibrateParam.data.info.aMin[i] = sensor->AccMin[i] ;
    }
    
    // 计算校验和
    uint32_t sum = 0 ;
    for ( i=0; i<sizeof(calibrateParam.data)/sizeof(uint32_t); i++ )
    {
      sum += calibrateParam.data.raw[i] ;
    }
    
    calibrateParam.sum = sum ;
    
    calibrateParam.sum_inv = ~sum ;
    
    // 存储参数到 flash
    if ( restoreCalibrateParamToFlash ( &calibrateParam ) )
    {
      sensor->AllReady = true ;      
      BSP_LED_ON(LED_R) ;         // 点亮红灯提示
      BSP_LED_OFF (LED_G) ;        // 关绿灯
      BSP_LED_OFF(LED_B) ;         // 关蓝灯          
    }      
  }
  
  
  
#else
  // 如果加速度的三个轴都已校正过,再开始校正磁场
  if  (  sensor->AccMaxReady[0] && sensor->AccMinReady[0] && 
                  sensor->AccMaxReady[1] && sensor->AccMinReady[1] &&
                  sensor->AccMaxReady[2] && sensor->AccMinReady[2]  )
  {
    if ( goodMagSamplesCount < 6 )
    {
      goodMagSamplesCount = 6 ; // 加速度校完后,三个主轴各有两个好的磁场采样点
    }

    
    // 如果当前的采样值与之前记录的所有采样值相比明显不同,则认可当前采样值    
    int16_t dx, dy, dz ;
    float minRatio = 0.3f ;
    for ( i=0; i<goodMagSamplesCount; i++ )
    {
      dx = goodMagSamples[i][0] - mx ;
      dy = goodMagSamples[i][1] - my ;
      dz = goodMagSamples[i][2] - mz ;
      
      // 差向量的长度小于当前向量本身长度的  minRatio 倍时,认为当前向量与其他向量的间距太近。
      if  (  dx*dx + dy*dy + dz*dz  <  (minRatio*minRatio) * ( mx*mx + my*my + mz*mz )  ) 
        break ;
    }
    if ( i == goodMagSamplesCount )
    {
      // 采纳当前采样值
      goodMagSamples [ goodMagSamplesCount ][0] = mx ;
      goodMagSamples [ goodMagSamplesCount ][1] = my ;
      goodMagSamples [ goodMagSamplesCount ][2] = mz ;
      goodMagSamplesCount ++ ;
    }
    
    
    
    // 如果好的采样点数量已足够,则计算拟合方程
    if ( goodMagSamplesCount >= MaxGoodMagSamplesCount )
    {
      // 计算原始方程的因子
      float (*p) [6] = MagOriginEquationFactors ;
      int16_t (*s) [3] = goodMagSamples ;
      for ( i=0; i<MaxGoodMagSamplesCount; i++ )
      {
        float weight = 1 ;
        if ( i < 6 )
          weight *= MainAxis_MagWeight ;       // 前 6 行是主轴方向测量的数据,为主轴方向的数据分配高权重

        p[i][0] = s[i][0] * s[i][0] * weight;
        p[i][1] = -2 * s[i][0]  * weight;
        p[i][2] = s[i][1] * s[i][1]  * weight;
        p[i][3] = -2 * s[i][1]  * weight;
        p[i][4] = s[i][2] * s[i][2]  * weight;
        p[i][5] = -2 * s[i][2]  * weight;
      }
      
      // 计算拟合方程的因子
      float (*x) [6] = MagEquationFactors ;
      float *y = MagEquationResults ;
      for (i=0; i<6; i++)
      {
        int j , k ;
        
        // 计算 x[i][:]
        for (j=0; j<6; j++)
        {
          x[i][j] = 0 ;
          for ( k=0; k<MaxGoodMagSamplesCount; k++ )
          {
            x[i][j] += p[k][j] * p[k][i] ;
          }
        }

        // 计算 y[i]
        y[i] = 0 ;
        for ( k=0; k<MaxGoodMagSamplesCount; k++ )
        {
          float weight = 1 ;
          if ( k < 6 )
            weight *= MainAxis_MagWeight ;       // 前 6 行是主轴方向测量的数据,为主轴方向的数据分配高权重
          y[i] += p[k][i] * weight ;
        }
        y[i] *= MagMeasuredRadius * MagMeasuredRadius ;        // 乘一个因子
      }
      
      // 求解拟合的方程
      if ( SolveLinearEquations ( (float*)x, y, 6, 6, y ) )
      {      
        // 计算校正参数
        float ratioX, ratioY, ratioZ ;
        float offsetX, offsetY, offsetZ ;

        offsetX = y[1]/y[0] ;
        offsetY = y[3]/y[2] ;
        offsetZ = y[5]/y[4] ;

        ratioX = sqrt(y[0]/y[4]) ;
        ratioY = sqrt(y[2]/y[4]) ;
        ratioZ = 1 ;    // 比例都以 Z 轴为参考
        
        
        sensor->MagMax[0] = MagMeasuredRadius / ratioX + offsetX ;
        sensor->MagMin[0] = (-MagMeasuredRadius) / ratioX + offsetX ;

        sensor->MagMax[1] = MagMeasuredRadius / ratioY + offsetY ;
        sensor->MagMin[1] = (-MagMeasuredRadius) / ratioY + offsetY ;

        sensor->MagMax[2] = MagMeasuredRadius / ratioZ + offsetZ ;
        sensor->MagMin[2] = (-MagMeasuredRadius) / ratioZ + offsetZ ;
        
        sensor->MagReady = true ;

      }
    }
    
  }

  
  // 如果校准已完成,点亮红灯提示
  bool allReady ;
  allReady = sensor->AccMaxReady[0] && sensor->AccMinReady[0] && 
                  sensor->AccMaxReady[1] && sensor->AccMinReady[1] &&
                  sensor->AccMaxReady[2] && sensor->AccMinReady[2] && 
                    sensor->MagReady ;

  
  
  if ( allReady )
  {
    // 清零校正参数结构体        不再进行清零操作,使calibrateParam保持之前的值
//    for ( i=0; i<sizeof(calibrateParam.data)/sizeof(uint32_t); i++ )
//    {
//      calibrateParam.data.raw[i] = 0 ;
//    }
    
    // 对各字段赋值
    for ( i=0; i<3; i++ )
    {
      calibrateParam.data.info.aMax[i] = sensor->AccMax[i] ;
      calibrateParam.data.info.aMin[i] = sensor->AccMin[i] ;
      calibrateParam.data.info.mMax[i] = sensor->MagMax[i] ;
      calibrateParam.data.info.mMin[i] = sensor->MagMin[i] ;
    }
    
    // 计算校验和
    uint32_t sum = 0 ;
    for ( i=0; i<sizeof(calibrateParam.data)/sizeof(uint32_t); i++ )
    {
      sum += calibrateParam.data.raw[i] ;
    }
    
    calibrateParam.sum = sum ;
    
    calibrateParam.sum_inv = ~sum ;
    
    // 存储参数到 flash
    if ( restoreCalibrateParamToFlash ( &calibrateParam ) )
    {
      sensor->AllReady = true ;      
      BSP_LED_ON(LED_R) ;         // 点亮红灯提示
      BSP_LED_OFF (LED_G) ;        // 关绿灯
      BSP_LED_OFF(LED_B) ;         // 关蓝灯                
    }  
  }

#endif  

}
Пример #3
0
void runCalibration4 ( AttitudeSensor* sensor )
{  

  int i ;
  entryCount ++ ;
  if ( entryCount >= SAMPLE_STEP )
    entryCount = 0 ;
  
  if ( entryCount != 0 )
    return ;
  
  if ( sensor->AllReady )
  {
    BSP_LED_ON(LED_R) ;         // 点亮红灯提示
    BSP_LED_OFF(LED_B) ;         // 关蓝灯              
    return ;
  }
  

  // 读取加速度计的低通+滑动平均滤波+跟随预测值
  int ax, ay, az , mx , my, mz ;
  ax = getAccXSlideAverage(sensor);
  ay = getAccYSlideAverage(sensor);
  az = getAccZSlideAverage(sensor);
  
  
  // 更新加速度的历史值队列
  for (i=0;i<N-1;i++)
  {
    recentAx[i] = recentAx[i+1] ;
    recentAy[i] = recentAy[i+1] ;
    recentAz[i] = recentAz[i+1] ;
  }
  recentAx [N-1] = ax ;
  recentAy [N-1] = ay ;
  recentAz [N-1] = az ;
  
  
  if ( validSamples < N )
  {
    validSamples ++ ;
    return ;
  }
  
  
  // 找到当前加速度的主轴
  int16_t* recentAp [3] = { recentAx, recentAy, recentAz };

  // 检查加速度是否趋于平稳
  bool stable = true ;
  for ( i=0; i<N; i++ )
  {
    int dx = recentAx[i] - recentAx[0] ;
    int dy = recentAy[i] - recentAy[0] ;
    int dz = recentAz[i] - recentAz[0] ;
    dx = dx < 0 ? -dx : dx ;
    dy = dy < 0 ? -dy : dy ;
    dz = dz < 0 ? -dz : dz ;
    if ( dx > deltaThr || dy > deltaThr || dz > deltaThr )
    {
      stable = false ;
      break ;
    }
  }
  
  if ( stable )
    stableCount ++ ;
  
  else
    stableCount = 0 ;

  
  
  // 如果加速度已经足够平稳,说明Sensor已处于静止状态,开始记录陀螺的值
  if ( stableCount > N )
  {
    gyroCaliSum [0] += sensor->gx ;
    gyroCaliSum [1] += sensor->gy ;
    gyroCaliSum [2] += sensor->gz ;
    BSP_LED_ON(LED_B) ;         // 亮灯提示    
  }
  else
  {
    BSP_LED_OFF(LED_B) ;         // 关闭指示灯
  } 
    
  
    
  // 如果校准已完成,点亮红灯提示
  bool allReady = false  ;

  if ( stableCount > 6*N )
  {
    gyroCaliSum[0] /= 5*N ;
    gyroCaliSum[1] /= 5*N ;
    gyroCaliSum[2] /= 5*N ;
    allReady = true ;
  }

  
  
  if ( allReady )
  {
    // 清零校正参数结构体        不再进行清零操作,使calibrateParam保持之前的值
//    for ( i=0; i<sizeof(calibrateParam.data)/sizeof(uint32_t); i++ )
//    {
//      calibrateParam.data.raw[i] = 0 ;
//    }
    
    // 对各字段赋值
    for ( i=0; i<3; i++ )
    {
      calibrateParam.data.info.g_offset[i] = gyroCaliSum[i] ;
    }
    
    // 计算校验和
    uint32_t sum = 0 ;
    for ( i=0; i<sizeof(calibrateParam.data)/sizeof(uint32_t); i++ )
    {
      sum += calibrateParam.data.raw[i] ;
    }
    
    calibrateParam.sum = sum ;
    
    calibrateParam.sum_inv = ~sum ;
    
    // 存储参数到 flash
    if ( restoreCalibrateParamToFlash ( &calibrateParam ) )
    {
      sensor->AllReady = true ;      
      BSP_LED_ON(LED_R) ;         // 点亮红灯提示
      BSP_LED_OFF(LED_B) ;         // 关蓝灯          
    }  
  }
}