Go to Post "No wheels, no problem, we can fix it in programming." - clean399 [more]
Home
Go Back   Chief Delphi > Technical > Programming > C/C++
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Reply
Thread Tools Rating: Thread Rating: 3 votes, 3.67 average. Display Modes
  #1   Spotlight this post!  
Unread 02-04-2012, 15:09
Ro13star Ro13star is offline
Registered User
FRC #0832
 
Join Date: Apr 2012
Location: roswell
Posts: 3
Ro13star is an unknown quantity at this point
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
Reply With Quote
  #2   Spotlight this post!  
Unread 02-04-2012, 15:14
Ether's Avatar
Ether Ether is offline
systems engineer (retired)
no team
 
Join Date: Nov 2009
Rookie Year: 1969
Location: US
Posts: 8,098
Ether has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond repute
Re: Encoder for Rpm help!

Quote:
Originally Posted by Ro13star View Post
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.
How did you confirm that the E4P encoder works by using a multi-meter?


Reply With Quote
  #3   Spotlight this post!  
Unread 02-04-2012, 15:17
Ether's Avatar
Ether Ether is offline
systems engineer (retired)
no team
 
Join Date: Nov 2009
Rookie Year: 1969
Location: US
Posts: 8,098
Ether has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond repute
Re: Encoder for Rpm help!

Quote:
Originally Posted by Ro13star View Post
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
The E4P encoder output is not PWM.

You can use just one channel, but then you would need to use the Counter class, not the Encoder class, to process the signal.


Reply With Quote
  #4   Spotlight this post!  
Unread 02-04-2012, 15:26
Jay Meldrum's Avatar
Jay Meldrum Jay Meldrum is offline
Registered User
FRC #0067 (H.O.T.)
Team Role: Engineer
 
Join Date: Jan 2012
Rookie Year: 2003
Location: Michigan
Posts: 42
Jay Meldrum has much to be proud ofJay Meldrum has much to be proud ofJay Meldrum has much to be proud ofJay Meldrum has much to be proud ofJay Meldrum has much to be proud ofJay Meldrum has much to be proud ofJay Meldrum has much to be proud ofJay Meldrum has much to be proud ofJay Meldrum has much to be proud of
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
		}
       }
}
__________________
2012-2015 - FRC 67 - Programming/Controls Lead Mentor
2003-2005 - FRC 857 - Driver

Check us out at http://www.hotteam67.org
Previous year design docs, programming tutorials, and more!

Last edited by Jay Meldrum : 02-04-2012 at 15:30.
Reply With Quote
  #5   Spotlight this post!  
Unread 12-04-2012, 10:53
rbmj rbmj is offline
Registered User
FRC #0612 (Chantilly Robotics)
Team Role: Alumni
 
Join Date: Apr 2011
Rookie Year: 2011
Location: DC Area/Fairfax County
Posts: 192
rbmj is a jewel in the roughrbmj is a jewel in the roughrbmj is a jewel in the rough
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(); }
};
The nice thing for this is that it lets you use PID with a jag and such.

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.
Reply With Quote
  #6   Spotlight this post!  
Unread 12-04-2012, 16:05
bob.wolff68's Avatar
bob.wolff68 bob.wolff68 is offline
Da' Mentor Man
FRC #1967
Team Role: Mentor
 
Join Date: Jan 2012
Rookie Year: 2007
Location: United States
Posts: 157
bob.wolff68 is just really nicebob.wolff68 is just really nicebob.wolff68 is just really nicebob.wolff68 is just really nicebob.wolff68 is just really nice
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
__________________
~~~~~~~~~~~~~~~~~~~
Bob Wolff - Software from the old-school
Mentor / C / C++ guy
Team 1967 - The Janksters - San Jose, CA
Reply With Quote
  #7   Spotlight this post!  
Unread 12-04-2012, 16:11
Ether's Avatar
Ether Ether is offline
systems engineer (retired)
no team
 
Join Date: Nov 2009
Rookie Year: 1969
Location: US
Posts: 8,098
Ether has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond repute
Re: Encoder for Rpm help!

Quote:
Originally Posted by bob.wolff68 View Post
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
For speed control of a shooter wheel, try this.


Reply With Quote
  #8   Spotlight this post!  
Unread 12-04-2012, 16:37
mikets's Avatar
mikets mikets is offline
Software Engineer
FRC #0492 (Titan Robotics)
Team Role: Mentor
 
Join Date: Jan 2010
Rookie Year: 2008
Location: Bellevue, WA
Posts: 671
mikets is a glorious beacon of lightmikets is a glorious beacon of lightmikets is a glorious beacon of lightmikets is a glorious beacon of lightmikets is a glorious beacon of lightmikets is a glorious beacon of light
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
__________________
Reply With Quote
  #9   Spotlight this post!  
Unread 12-04-2012, 17:43
rbmj rbmj is offline
Registered User
FRC #0612 (Chantilly Robotics)
Team Role: Alumni
 
Join Date: Apr 2011
Rookie Year: 2011
Location: DC Area/Fairfax County
Posts: 192
rbmj is a jewel in the roughrbmj is a jewel in the roughrbmj is a jewel in the rough
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;
    }
};
Some integration code (note that we were working with a counter hooked up to a hall effect sensor detecting a single magnet in the wheel, so one tick was one rotation):
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();
}
You can do more stuff, like adding in a startup burst to get it close and then enable the PID controller to fine tune the speed. We ended up with a quarter second burst of full power before we started the PID controller. Make sure you set the starting speed (two_jags::speed) to your startup speed before, otherwise you'll put the motors back to zero power and defeat the whole purpose of the start speed.

Last edited by rbmj : 13-04-2012 at 10:05.
Reply With Quote
  #10   Spotlight this post!  
Unread 12-04-2012, 18:28
mikets's Avatar
mikets mikets is offline
Software Engineer
FRC #0492 (Titan Robotics)
Team Role: Mentor
 
Join Date: Jan 2010
Rookie Year: 2008
Location: Bellevue, WA
Posts: 671
mikets is a glorious beacon of lightmikets is a glorious beacon of lightmikets is a glorious beacon of lightmikets is a glorious beacon of lightmikets is a glorious beacon of lightmikets is a glorious beacon of light
Re: Encoder for Rpm help!

Quote:
Originally Posted by rbmj View Post
It's pretty easy actually. WPILib makes this easy for you.

We actually had two motors, so...
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.
Reply With Quote
  #11   Spotlight this post!  
Unread 13-04-2012, 10:04
rbmj rbmj is offline
Registered User
FRC #0612 (Chantilly Robotics)
Team Role: Alumni
 
Join Date: Apr 2011
Rookie Year: 2011
Location: DC Area/Fairfax County
Posts: 192
rbmj is a jewel in the roughrbmj is a jewel in the roughrbmj is a jewel in the rough
Re: Encoder for Rpm help!

Quote:
Originally Posted by mikets View Post
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);
Yeah, that (typo) is what happens when you're being lazy edited.

And I haven't heard of a sync group...

Anyway, what we had worked very well for us.
Reply With Quote
  #12   Spotlight this post!  
Unread 13-04-2012, 10:09
Joe Ross's Avatar Unsung FIRST Hero
Joe Ross Joe Ross is offline
Registered User
FRC #0330 (Beachbots)
Team Role: Engineer
 
Join Date: Jun 2001
Rookie Year: 1997
Location: Los Angeles, CA
Posts: 8,576
Joe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond repute
Re: Encoder for Rpm help!

Quote:
Originally Posted by mikets View Post
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);

sync groups only apply when using CAN. PWM is always synced.
Reply With Quote
  #13   Spotlight this post!  
Unread 13-04-2012, 22:03
Ken Streeter's Avatar
Ken Streeter Ken Streeter is offline
Let the MAYHEM begin!
FRC #1519 (Mechanical Mayhem)
Team Role: Engineer
 
Join Date: Feb 2005
Rookie Year: 2005
Location: Team: Milford, NH; Me: Bedford, NH
Posts: 471
Ken Streeter has a reputation beyond reputeKen Streeter has a reputation beyond reputeKen Streeter has a reputation beyond reputeKen Streeter has a reputation beyond reputeKen Streeter has a reputation beyond reputeKen Streeter has a reputation beyond reputeKen Streeter has a reputation beyond reputeKen Streeter has a reputation beyond reputeKen Streeter has a reputation beyond reputeKen Streeter has a reputation beyond reputeKen Streeter has a reputation beyond repute
Re: Encoder for Rpm help!

Quote:
Originally Posted by Ro13star View Post

public:
...
shooter_motor(3),
shooter_motor2(4),
left_shooter (3,4,false)

...

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
I think that the problem you are having is a side effect of wiring only the A channel. I think that in order to get the encoder to work with just the A channel, you will need to ensure that it is a "1x" encoder. (Note that I've never tried this, we always hook up both the A and B channels, even if we are only using "1x" counting.) To use 1X counting, when you initialize the Encoder, you will need to use a line like the following:

Code:
left_shooter(3,4,false,CounterBase.EncodingType.k1X)
__________________
Ken Streeter - Team 1519 - Mechanical Mayhem (Milford Area Youth Homeschoolers Enriching Minds)
2015 NE District Winners with 195 & 2067, 125 & 1786, 230 & 4908, and 95 & 1307
2013 World Finalists & Archimedes Division Winners with 33 & 469
2013 & 2012 North Carolina Regional Winners with teams 435 & 4828 and 1311 & 2642
2011, 2010, 2006 Granite State Regional Winners with teams 175 & 176, 1073 & 1058, and 1276 & 133
Team 1519 Video Gallery - including Chairman's Video, and the infamous "Speed Racer!"

Last edited by Ken Streeter : 13-04-2012 at 23:22. Reason: fixing "code" snippet to be properly indented
Reply With Quote
  #14   Spotlight this post!  
Unread 13-04-2012, 22:15
Ether's Avatar
Ether Ether is offline
systems engineer (retired)
no team
 
Join Date: Nov 2009
Rookie Year: 1969
Location: US
Posts: 8,098
Ether has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond repute
Re: Encoder for Rpm help!

Quote:
Originally Posted by Ken Streeter View Post
I think that the problem you are having is a side effect of wiring only the A channel. I think that in order to get the encoder to work with just the A channel, you will need to ensure that it is a "1x" encoder.
To get the encoder to work with only one channel connected, you should use the Counter class instead of the Encoder class.

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.
Reply With Quote
Reply


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump


All times are GMT -5. The time now is 03:02.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi