|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
|
|
Thread Tools |
Rating:
|
Display Modes |
|
|
|
#1
|
|||
|
|||
|
Encoder for Rpm help!
Hi, i am a new programmer for my team and i am having problems with using the data from the encoder in the program. i have confirmed the encoder works with a multi-meter. the encoder is a us Digital e4p.
this is the relevant part of my code please help: class RobotOscar : public IterativeRobot { // RobotDrive myRobotDrive; // robot drive system Jaguar shooter_motor; Jaguar shooter_motor2; Encoder left_shooter; double count; public: RobotOscar(void): shooter_motor(3), shooter_motor2(4), left_shooter (3,4,false) ... ... void TeleopInit(void) { printf("Telop Init Entry\n"); left_shooter.Start(); left_shooter.Reset(); } ... ... void TeleopContinuous(void) { while(IsEnabled() && IsOperatorControl()){ count=left_shooter.Get(); printf("count= %f \n", count); } } also can you use one pwm to a digital imput to get just the A channel from the encoder for rpm only. << is the current set up |
|
#2
|
||||
|
||||
|
Re: Encoder for Rpm help!
Quote:
|
|
#3
|
||||
|
||||
|
Re: Encoder for Rpm help!
Quote:
You can use just one channel, but then you would need to use the Counter class, not the Encoder class, to process the signal. |
|
#4
|
||||
|
||||
|
Re: Encoder for Rpm help!
If you are using a digital I/O/PWM encoder here is an example of code.
(Note: we use pointers) Code:
class BuiltinDefaultCode : public IterativeRobot
{
//Declare Encoders
Encoder *m_Encoder1;
public:
BuiltinDefaultCode(void)
{
//Initialize encoders
m_Encoder1 = new Encoder(1, 2, true);
m_Encoder1 -> SetDistancePerPulse(1);
m_Encoder1 -> SetMaxPeriod(1.0);
m_Encoder1 -> Start();
double m_Encoder1Distance;
double m_Encoder1Rate;
void TeleopSensorUpdater(void)
{
m_Encoder1Distance = m_Encoder1 -> GetDistance(); //Returns the amount of counts since the last reset
m_Encoder1Rate = m_Encoder1 -> GetRate(); //Returns the rate in pulses/second
}
}
}
Last edited by Jay Meldrum : 02-04-2012 at 15:30. |
|
#5
|
|||
|
|||
|
Re: Encoder for Rpm help!
We do something similar to jsmeldru...
Code:
#include <PIDSource.h>
#include <Counter.h>
class freq_pid : public PIDSource {
private:
Counter& count;
public:
freq_pid(Counter& c) : count(c) {}
double frequency() { return 1/count.GetPeriod(); }
double PIDGet() { return frequency(); }
};
We take everything by reference since we centralize all of our sensor port data in one file. Note that that frequency is in hz. If you want rpm you can just change the 1 to a 60. Last edited by rbmj : 12-04-2012 at 10:55. |
|
#6
|
||||
|
||||
|
Re: Encoder for Rpm help!
This looks nice. Now, my question is how to integrate this with a PIDController and Jaguar to make a speed-based/rpm-based PID Control. We played with modifying PIDOutput() in a super-class of Jaguar such that it 'accumulated' rather than just sending the total_error to the Jag which effectively stops the Jag when you get to an error of zero (hence a positional PID controller as it is today)...
Seems that LOTS of people would want to be able to do this, but I wasn't able to find such a thing this year and so we tried creating our own and didn't have luck. Anyone have experience here? bob |
|
#7
|
||||
|
||||
|
Re: Encoder for Rpm help!
Quote:
|
|
#8
|
||||
|
||||
|
Re: Encoder for Rpm help!
We have created a generic PID controller based on the WPI PID controller that, among other things, can handle speed control.
http://proj.titanrobotics.net/hg/Frc...b/TrcPIDCtrl.h |
|
#9
|
|||
|
|||
|
Re: Encoder for Rpm help!
It's pretty easy actually. WPILib makes this easy for you.
We actually had two motors, so... Code:
template<class T>
T coerce(T val, T min, T max) {
if (val < min) {
return min;
}
else if (val > max) {
return max;
}
else {
return val;
}
}
class two_jags : public PIDOutput {
private:
Jaguar& jag1;
Jaguar& jag2;
float speed;
public:
two_jags(Jaguar& a, Jaguar& b) : jag1(a), jag2(b), speed(0.0) {}
void PIDWrite(float output) {
speed = coerce(output + speed, -1.0f, 1.0f);
jag1.PIDWrite(speed);
jag2.PIDWrite(speed);
}
void reset() {
speed = 0.0;
}
};
Code:
two_jags jags(jag1, jag2);
freq_pid freq(cnt);
PIDController shooter_ctl(0.005, 0.0, 0.002, freq, jags);
shooter_ctl.SetTolerance(4.0); //accept a 4% steady state error
shooter_ctl.SetInputRange(0.0, 75.0); //our max freq was 75 hz
shooter_ctl.SetOutputRange(-0.25, 0.25); //only ramp a little at a time
//...
void enable_shooters(float freq) {
jags.reset(); //zero out the accumulator
shooter_ctl.SetSetpoint(freq);
shooter_ctl.Enable();
}
Last edited by rbmj : 13-04-2012 at 10:05. |
|
#10
|
||||
|
||||
|
Re: Encoder for Rpm help!
Since you are using two motors, you should define the two motors in a sync group so you can synchronize them. BTW, I think you have a typo in the parameter of two_jags:: PIDWrite(float output);
Last edited by mikets : 12-04-2012 at 18:30. |
|
#11
|
|||
|
|||
|
Re: Encoder for Rpm help!
Quote:
edited.And I haven't heard of a sync group... Anyway, what we had worked very well for us. |
|
#12
|
||||||
|
||||||
|
Re: Encoder for Rpm help!
Quote:
sync groups only apply when using CAN. PWM is always synced. |
|
#13
|
|||||
|
|||||
|
Re: Encoder for Rpm help!
Quote:
Code:
left_shooter(3,4,false,CounterBase.EncodingType.k1X) Last edited by Ken Streeter : 13-04-2012 at 23:22. Reason: fixing "code" snippet to be properly indented |
|
#14
|
||||
|
||||
|
Re: Encoder for Rpm help!
Quote:
In the Counter class, you can specify either 1x or 2x decoding. I think it works this way: With 1x, it counts rising edges only. With 2x, it counts both rising and falling edges. Last edited by Ether : 13-04-2012 at 22:19. |
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|