gpt4 book ai didi

Arduino 中的 C++ 结构多态性

转载 作者:行者123 更新时间:2023-11-28 01:51:38 25 4
gpt4 key购买 nike

我有一个名为 Quadruped_Robot 的类,它有四个结构,fRightfLeftbRightbLeft 继承自基础结构 Leg。在 Arduino 中,我尝试通过循环驱动 8 个伺服电机,这四个结构保存伺服驱动器 channel 值。我创建了一个指向这四个结构的指针数组,以便函数 actuateLeg 可以将 PWM 信号发送到在运行时确定的适当 channel 。然而,没有伺服系统响应,并且在检查 myLeg->channels[0]myLeg->channels[1] 给出的值时,它们报告的值是在数以千计的范围内,包括正数和负数。但是,值应介于 07 之间。为什么当我尝试使用 -> 运算符访问它们时 channel 值不正确?

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

//default address
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

class Quadruped_Robot{

private:
//minimum and maximum pulse length count
//valid range: [0,4096]
//0 degrees: 200
//60 degrees: 360
//90 degrees: 510
//180 degrees: 915
size_t SERVOMIN= 200;
size_t SERVOMAX= 915;

//phase shift between upper and lower leg actuation in milliseconds
size_t OFFSET= 1000;

//pulse length to servo motors
size_t PULSE_LENGTH= 100;

struct Leg{
int channels[2];
bool started;
virtual void foo()=0;
};

struct fRight:Leg{
//channel numbers on the PWM/Servo driver for the front right leg
//0= upper leg
//1= lower leg
int channels[2]= {0, 1};
bool started= false;
virtual void foo(){}
};

struct fLeft:Leg{
//channel numbers on the PWM/Servo driver for the front left leg
//2= upper leg
//3= lower leg
int channels[2]= {2, 3};
bool started= false;
virtual void foo(){}
};

struct bRight:Leg{
//channel numbers on the PWM/Servo driver for the back right leg
//4= upper leg
//5= lower leg
int channels[2]= {4, 5};
bool started= false;
virtual void foo(){}
};

struct bLeft:Leg{
//channel numbers on the PWM/Servo driver for the back left leg
//6= upper leg
//7= lower leg
int channels[2]= {6, 7};
bool started= false;
virtual void foo(){}
};

//bool value indicating whether the servos have begun moving
bool started= false;

//holds the previous timestamp
unsigned long prevTime;

public:

Leg* myLegs[4]= {new fRight, new fLeft, new bRight, new bLeft};

void actuateLeg(size_t leg){
prevTime= millis();
Leg *myLeg= myLegs[leg];
size_t PWM= SERVOMIN;

//Actuate upper leg and wait until the phase shift time has elapsed to actuate the lower leg
while(millis()-prevTime < OFFSET){
pwm.setPWM(myLeg->channels[0], 0, PWM );
Serial.println(myLeg->channels[0]);
}
prevTime= millis();

//Actuate lower leg and wait until the phase shift time has elapsed to actuate the upper leg again
while(millis()-prevTime < OFFSET){
pwm.setPWM(myLeg->channels[1], 0, PWM );
Serial.println(myLeg->channels[1]);
}
prevTime= millis();
PWM= SERVOMAX;

//Actuate upper leg and wait until the phase shift time has elapsed to actuate the lower leg again
while(millis()-prevTime < OFFSET){
pwm.setPWM(myLeg->channels[0], 0, PWM );
Serial.println(myLeg->channels[0]);
}
prevTime= millis();

while(millis()-prevTime < OFFSET){
pwm.setPWM(myLeg->channels[1], 0, PWM );
Serial.println(myLeg->channels[1]);
}
delete myLeg;
}

void walk(){
actuateLeg(0);
actuateLeg(2);
actuateLeg(1);
actuateLeg(3);
}

};

//Create a Quadruped_Robot object
Quadruped_Robot myQuadruped;

void setup() {
//Begin serial communication at 9600 bps
Serial.begin(9600);

//MG996R servo runs at 50 Hz
pwm.setPWMFreq(50);
pwm.begin();

}

void loop() {
myQuadruped.walk();

}

最佳答案

您的每个腿类(fRight、fLeft、bRight、bLeft)都会创建两个变量:

int channels[2]= {2, 3};
bool started= false;

...这会创建一个无法通过 Leg 指针访问的不同拷贝。

您需要更改为类似以下内容以确保您在基本结构 Leg 中设置值。

struct fRight :  Leg
{
fRight() {
started = false;
channels[0] = 0;
channels[1] = 1;
}
virtual void foo() {}
};

虽然您甚至可能不需要这些单独的类(取决于您的纯虚拟 foo() 需要做什么)。如果您要将 Leg 更改为:

struct Leg
{
Leg(int channel1, int channel2) :
started {false}
{
channels[0] = channel1;
channels[1] = channel1;
}

int channels[2];
bool started;
//virtual void foo() = 0;
};

...你可以实例化:

Leg* myLegs[4] = { new Leg{0,1}, new Leg{2,3}, new Leg{4,5}, new Leg{6,7} }

关于Arduino 中的 C++ 结构多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42818372/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com