首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >c++数组的值一直被切换

c++数组的值一直被切换
EN

Stack Overflow用户
提问于 2020-08-15 21:38:36
回答 1查看 55关注 0票数 0

我有一个arduino程序,当它处于一个奇怪的角度时,它运行一个伺服,但是在5秒后,如果仍然在那个奇怪的角度,设置它作为新的中心。问题是,由于某种原因,当我将当前旋转的角度设置为新的中心时,值就会被混淆。此外,中心的值似乎在五秒钟之前就更新了。我认为这与编译器有关。我的密码在这里:

代码语言:javascript
复制
/*
   Arduino and MPU6050 Accelerometer and Gyroscope Sensor Tutorial
   by Dejan, https://howtomechatronics.com
*/

#include <Wire.h>
#include <Servo.h>

#define SERVO_PIN    9  //PWM pin that is connected to the servo
Servo demoServo;        //create a servo object
int servoAngle = 0;     //servo angle which can vary from 0 - 180

const int MPU = 0x68; // MPU6050 I2C address
float AccX, AccY, AccZ;
float GyroX, GyroY, GyroZ;
float accAngleX, accAngleY, gyroAngleX, gyroAngleY, gyroAngleZ;
float roll, pitch, yaw;
float rot[1];
float AccErrorX, AccErrorY, GyroErrorX, GyroErrorY, GyroErrorZ;
float elapsedTime, currentTime, previousTime;
int c = 0;
bool shake;
int shakeTime = 0;
float stablePos[1];


void setup() {
  Serial.begin(19200);
  Wire.begin();                      // Initialize comunication
  Wire.beginTransmission(MPU);       // Start communication with MPU6050 // MPU=0x68
  Wire.write(0x6B);                  // Talk to the register 6B
  Wire.write(0x00);                  // Make reset - place a 0 into the 6B register
  Wire.endTransmission(true);        //end the transmission
  demoServo.attach(SERVO_PIN);
  delay(20);
  
  stablePos[0] = 0;
  stablePos[1] = 0;

  rot[0] = 0;
  rot[1] = 1;
}

void setIMU(float rot[])
{
  // === Read acceleromter data === //
  Wire.beginTransmission(MPU);
  Wire.write(0x3B); // Start with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU, 6, true); // Read 6 registers total, each axis value is stored in 2 registers
  //For a range of +-2g, we need to divide the raw values by 16384, according to the datasheet
  AccX = (Wire.read() << 8 | Wire.read()) / 16384.0; // X-axis value
  AccY = (Wire.read() << 8 | Wire.read()) / 16384.0; // Y-axis value
  AccZ = (Wire.read() << 8 | Wire.read()) / 16384.0; // Z-axis value
  // Calculating Roll and Pitch from the accelerometer data
  accAngleX = (atan(AccY / sqrt(pow(AccX, 2) + pow(AccZ, 2))) * 180 / PI) - 0.93; // AccErrorX ~(0.58) See the calculate_IMU_error()custom function for more details
  accAngleY = (atan(-1 * AccX / sqrt(pow(AccY, 2) + pow(AccZ, 2))) * 180 / PI) - 4.23; // AccErrorY ~(-1.58)

  // === Read gyroscope data === //
  previousTime = currentTime;        // Previous time is stored before the actual time read
  currentTime = millis();            // Current time actual time read
  elapsedTime = (currentTime - previousTime) / 1000; // Divide by 1000 to get seconds
  Wire.beginTransmission(MPU);
  Wire.write(0x43); // Gyro data first register address 0x43
  Wire.endTransmission(false);
  Wire.requestFrom(MPU, 6, true); // Read 4 registers total, each axis value is stored in 2 registers
  GyroX = (Wire.read() << 8 | Wire.read()) / 131.0; // For a 250deg/s range we have to divide first the raw value by 131.0, according to the datasheet
  GyroY = (Wire.read() << 8 | Wire.read()) / 131.0;
  GyroZ = (Wire.read() << 8 | Wire.read()) / 131.0;
  // Correct the outputs with the calculated error values
  GyroX = GyroX + 0.43; // GyroErrorX ~(-0.56)
  GyroY = GyroY + 0.63; // GyroErrorY ~(2)
  GyroZ = GyroZ + 1.67; // GyroErrorZ ~ (-0.8)

  // Currently the raw values are in degrees per seconds, deg/s, so we need to multiply by sendonds (s) to get the angle in degrees
  gyroAngleX = gyroAngleX + GyroX * elapsedTime; // deg/s * s = deg
  gyroAngleY = gyroAngleY + GyroY * elapsedTime;
  yaw =  yaw + GyroZ * elapsedTime;

  // Complementary filter - combine acceleromter and gyro angle values
  roll = 0.96 * gyroAngleX + 0.04 * accAngleX;
  pitch = 0.96 * gyroAngleY + 0.04 * accAngleY;
  
  rot[0] = pitch-10 > rot[0] || pitch+10 < rot[0] ? pitch : rot[0];
  rot[1] = roll-10 > rot[1] || roll+10 < rot[1] ? roll : rot[1];

}

void loop() {
  setIMU(rot);

  Serial.print("STABLE AT:");
  Serial.print(stablePos[0]);
  Serial.print("/");
  Serial.print(stablePos[1]);
  Serial.print("\t CURRENTLY AT:");
  Serial.print(rot[0]);
  Serial.print("/");
  Serial.println(rot[1]);

  
  shake = (rot[0]>stablePos[0]+20 || rot[0]<stablePos[0]-20) ? true : (rot[1]>stablePos[1]+20 || rot[1]<stablePos[1]-20);
  shakeTime = shake && shakeTime == 0 ? millis() + 5000 : shakeTime;
  if (shakeTime < millis() && shakeTime != 0){
    shakeTime = 0;
    shake = false;
    
    stablePos[0] = rot[0];
    stablePos[1] = rot[1];
  }
  
  Serial.println(shake);
  //Serial.println(shakeTime/1000);

  demoServo.write(shake ? 180 : 0); 
  
}

在这里可以看到测试的输出:

代码语言:javascript
复制
STABLE AT:0.00/0.00  CURRENTLY AT:0.00/0.00
0
STABLE AT:0.00/0.00  CURRENTLY AT:0.00/0.00
0
STABLE AT:0.00/0.00  CURRENTLY AT:0.00/-0.00
0
STABLE AT:0.00/0.00  CURRENTLY AT:0.00/-0.14
0
STABLE AT:0.00/0.00  CURRENTLY AT:0.00/-0.26
0
STABLE AT:0.00/0.00  CURRENTLY AT:0.00/0.05
0
STABLE AT:0.00/10.98     CURRENTLY AT:10.98/0.41
0
STABLE AT:0.00/10.98     CURRENTLY AT:10.98/-0.00
0
STABLE AT:0.00/10.98     CURRENTLY AT:10.98/0.16
0
STABLE AT:0.00/10.98     CURRENTLY AT:10.98/0.00
0
STABLE AT:0.00/10.98     CURRENTLY AT:10.98/1.49
0
STABLE AT:0.00/10.98     CURRENTLY AT:10.98/1.86
0
STABLE AT:0.00/10.98     CURRENTLY AT:10.98/0.00
0
STABLE AT:0.00/21.30     CURRENTLY AT:21.30/0.63
1
STABLE AT:0.00/21.30     CURRENTLY AT:21.30/2.57
1
STABLE AT:0.00/21.30     CURRENTLY AT:21.30/2.70
1
STABLE AT:0.00/21.30     CURRENTLY AT:21.30/2.69
1
STABLE AT:0.00/31.95     CURRENTLY AT:31.95/2.56
1
STABLE AT:0.00/31.95     CURRENTLY AT:31.95/-0.00
1
STABLE AT:0.00/31.95     CURRENTLY AT:31.95/-0.00
1

如您所见,不仅在将10.98布尔值设置为2之前,稳定的位置更新为shake,而且位置也发生了反转。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-08-15 21:50:57

float stablePos[1];是一个由一个元素组成的数组;唯一有效的索引是stablePos[0]。通过访问stablePos[1],您的程序将显示未定义的行为。rot也是如此。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63431042

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档