Hey all,
This is our code for Logomotion. Feel free to take a look.
Hey all,
This is our code for Logomotion. Feel free to take a look.
Ugh, looks like we forgot to attach the code :mad: I suppose we will have to wait until at least tomorrow to grab the code and post it, sorry folks.
Alright, now that I finally get a chance to post it, here is the Robodox-team 599 2011 Logomotion robot code, available for all.
Enjoy
Robodox_2011_Chiropractor.zip (2.86 MB)
Robodox_2011_Chiropractor.zip (2.86 MB)
I’ve always been curious as to why teams use pointers and new rather than objects. Why did your team use dynamic memory allocation?
WizenedEE, most of what I have learned about coding has come from mentors, so correct me if I’m wrong. We used pointers and new to avoid virtual errors and rewrites and because of different inheritances in the library provided to us. In most cases, it was simply easier to create new, temporary copies of variables than to work around the code that we didn’t write and didn’t want to rewrite. I hope that answers your question.
Well, I’m pretty new to the WPILib, but this is what I would do.
class Fred2 : public SimpleRobot {
public:
Fred2();
~Fred2();
void Autonomous();
void OperatorControl();
private:
OperatorConsole opCon;
/*Drivetrain*/
CANJaguar frontLeftWheelMtr;
CANJaguar rearLeftWheelMtr;
CANJaguar frontRightWheelMtr;
CANJaguar rearRightWheelMtr;
RobotDrive drivetrain;
/*Arm*/
CANJaguar longArmMtr;
CANJaguar shortArmMtr;
CANJaguar wristMtr;
Relay clawRly;
DigitalInput clawClosedSwitch;
DigitalInput clawOpenedSwitch;
/*Deployer*/
Deployer deployer;
/*Flippers*/
Servo flipperReleaseServo;
};
Fred2::Fred2() :
/*Drivetrain*/
frontLeftWheelMtr(frontLeftWheelMtrDevNum),
rearLeftWheelMtr(rearLeftWheelMtrDevNum),
frontRightWheelMtr(frontRightWheelMtrDevNum),
rearRightWheelMtr(rearRightWheelMtrDevNum),
drivetrain(frontLeftWheelMtr, rearLeftWheelMtr,
frontRightWheelMtr, rearRightWheelMtr),
/*Arm*/
/*Motors*/
longArmMtr(longArmMtrDevNum),
shortArmMtr(shortArmMtrDevNum),
wristMtr(wristMtrDevNum),
clawRly(clawRlyChannel),
/*Sensors*/
clawClosedSwitch(digitalModuleSlot, clawClosedSwitchChannel),
clawOpenedSwitch(digitalModuleSlot, clawOpenedSwitchChannel),
/*Flippers*/
flipperReleaseServo(digitalModuleSlot, flipperReleaseServoChannel)
{ /*Init Code*/
drivetrain.SetInvertedMotor(RobotDrive::kFrontLeftMotor,
driveMotorInvert[0]);
drivetrain.SetInvertedMotor(RobotDrive::kRearLeftMotor,
driveMotorInvert[1]);
drivetrain.SetInvertedMotor(RobotDrive::kFrontRightMotor,
driveMotorInvert[2]);
drivetrain.SetInvertedMotor(RobotDrive::kRearRightMotor,
driveMotorInvert[3]);
}
I didn’t have to rewrite any functions to avoid using new, so I don’t really know what you’re getting at. I’m just wondering if it’s that people don’t teach this method (why?) or if there’s actually a good reason for it.
I think we went with pointers in the functions where we would need to use digital sensors because of problems with the sensor maintaining its state and not refreshing properly. Other than that, I don’t think there is any reason that you should not use objects in your code.
Can you please explain why pointers make the digital sensors refresh properly?
If I recall correctly, pointers are constructed when the code is first called then destructed when they are no longer needed. The code is called upon three times, once when the robot first turns on, when autonomous begins, and finally when the tele-op period begins. With pointers, the values of the variables are reset to their original position because a new copy is constructed for autonomous and a new copy is constructed for teleop. Otherwise, as with an object, when tele-op begins, the state that the sensor was last left in will now be its zero state. This could cause problems with an automatic lift system using an encoder or with gyroscopes on the robot.
Objects allocated with new are only destructed when delete is called on them. Statically allocated objects act essentially this way, though.
The code is called upon three times, once when the robot first turns on, when autonomous begins, and finally when the tele-op period begins.
The constructor? That’s only called when FRC_UserProgram_StartupLibraryInit() is called (defined in the START_ROBOT_CLASS macro) and never again.
With pointers, the values of the variables are reset to their original position because a new copy is constructed for autonomous and a new copy is constructed for teleop.
I’m not sure what you mean by this. The copy constructor is disabled in SensorBase, which is inherited by all of the sensor classes, and new is only called in your class’s constructor.
Otherwise, as with an object, when tele-op begins, the state that the sensor was last left in will now be its zero state. This could cause problems with an automatic lift system using an encoder or with gyroscopes on the robot.
Do you have a source for that? I didn’t think there was any difference between dynamically and statically allocated objects functionally.
WizenedEE, you are correct in what you have stated, and to be honest, I don’t quite remember why we went with pointers instead of objects. I don’t have much C++ experience, just one season of FRC and I cannot for the life of me remember why we went with pointers.
Oh okay, it’s just been something I’ve been wondering about for a while.
There can be. If you have a base class with virtual function DoStuff(), the generic pointer base* will call derivitives DoStuff(), but a static base will call its own DoStuff.
ex:
class base {
virtual void DoStuff(){
cout<<"in base"<<endl;
}
}
class deriv : public base {
virtual void DoStuff(){
cout<<"in deriv"<<endl;
}
}
base* baseptr = new base(); //dynamic
base basestatic = base(); //static
base* derivptr = new deriv(); //dynamic
base derivstatic = deriv(); //static
baseptr->DoStuff(); //==> in base
basestatic.DoStuff(); //==> in base
derivptr->DoStuff(); //==> in deriv
derivstatic.DoStuff(); //==> in base
byteit101, you’ve perfectly described the exact situation I made the programmers on 599 use pointers. We derived our own classes for some of the sensors to implement some custom functionality. Yes, we could have still done everything with statically allocated objects but I wanted to give the students some exposure to working with pointers and dynamic allocation because that’s something that a lot of people in my CS classes in college had trouble with.