Go to Post Don't let the teams here be so much of an intimidation to you, but instead, an inspiration. They all had to start from the beginning, too. - Amanda Morrison [more]
Home
Go Back   Chief Delphi > Technical > Programming > Java
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Reply
 
Thread Tools Rate Thread Display Modes
  #1   Spotlight this post!  
Unread 07-02-2013, 20:44
Ether's Avatar
Ether Ether is offline
systems engineer (retired)
no team
 
Join Date: Nov 2009
Rookie Year: 1969
Location: US
Posts: 8,043
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: Configure Timers


Quote:
Sampling the signal does not provide any lag... I do not understand what you mean by average, because the points are not being averaged.
Averaging causes lag. Speed is your process variable, not counts. In the code you posted, sampling the counts every 200ms and dividing the difference by the difference in time produces a speed signal which is the average speed over the past 7.7 revolutions, not the instantaneous speed at the moment of sampling. It's effectively a low-pass filter, which introduces lag. That average speed lags the instantaneous speed, if there was any acceleration taking place during the past 200ms.

If instead you use the WPILib GetPeriod() method, this happens:

1) the FPGA returns the elapsed time (measured with the FPGA's 1MHz clock) between the most recent N+1 counts detected, then

2) WPILib divides that elapsed time by N.

You can then use this in your code to calculate speed. Using this method, you don't need to average the speed over seven and a half revolutions to get a clean signal. One-quarter of a revolution will given you a clean speed signal, with less phase lag.


Quote:
I can shorten my sample time in order to reduce lag.
Sure you can. But your computed speed will get noisier, due to the 1ms resolution of your timer and the discrete nature of the counts.


Quote:
I have never been able to get a clean signal from the period() function.
The default value in WPILib is to set up the FPGA to return the elapsed time between the most recent 2 counts (i.e. N=1). Have you ever changed that default value? If not, I can understand why you couldn't get it to give you a clean signal at high speeds.


Quote:
I haven't looked into why the getPeriod() function produces a signal so noisy
I have. At high speeds with many CPR, the FPGA 1MHz timer and 153KHz polling frequency aren't fast enough to measure the elapsed time between just 2 counts without introducing excessive jitter. That's why you need to configure the FPGA to return the elapsed time between the N+1 most recent counts, instead of the most recent 2 counts, when using an encoder. If you use a one-per-rev counter, the FPGA default value N=1 works well.


Quote:
why do i need to ask for a speed signal every 10 milliseconds? The Driver Station Packets are sent every 20 milliseconds, so any calculations done faster than that, are simply being thrown out and not making its way to the robot.
The speed signal comes from the sensor on the robot, not from the Driver Station. The only time the 20ms would come into play is when the driver changes the speed setpoint, which is typically a step change, not something that's continuously changing every 20ms.


Quote:
As for the control of bang-bang, It is a good way to control velocity of the wheel for its simplicity, but you need to manage the oscillations around the setpoint.... You are ignoring inertia
You've got that backwards. I'm not ignoring inertia, I'm depending on it. Inertia plays a critical role in making bang-bang speed control work cleanly. Bang-bang speed control likes a high inertia load, a fast control loop, and low phase lag in the speed feedback. Compared to the approach you are using, GetPeriod() gives a smaller phase lag for the same signal-to-noise. And bang-bang code is so simple that it's not a problem to run it at 10ms. It also has the fastest spinup and recovery time.


Quote:
I would love a nanosecond timer
GetPPCTimestamp(). It's not nanosecond but it's better than millisecond.


Reply With Quote
  #2   Spotlight this post!  
Unread 08-02-2013, 10:25
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,561
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: Configure Timers

Quote:
Originally Posted by Ether View Post
GetPPCTimestamp(). It's not nanosecond but it's better than millisecond.
I haven't been able to find that implemented in java.
Reply With Quote
  #3   Spotlight this post!  
Unread 08-02-2013, 11:10
NotInControl NotInControl is offline
Controls Engineer
AKA: Kevin
FRC #2168 (Aluminum Falcons)
Team Role: Engineer
 
Join Date: Oct 2011
Rookie Year: 2004
Location: Groton, CT
Posts: 261
NotInControl has a reputation beyond reputeNotInControl has a reputation beyond reputeNotInControl has a reputation beyond reputeNotInControl has a reputation beyond reputeNotInControl has a reputation beyond reputeNotInControl has a reputation beyond reputeNotInControl has a reputation beyond reputeNotInControl has a reputation beyond reputeNotInControl has a reputation beyond reputeNotInControl has a reputation beyond reputeNotInControl has a reputation beyond repute
Re: Configure Timers

Quote:
Originally Posted by Ether View Post


In the code you posted, sampling the counts every 200ms and dividing the difference by the difference in time produces a speed signal which is the average speed over the past 7.7 revolutions...

Thanks for clearing that up. Agreed,It's lag due to the derivative of one timestamp. In my case its 200ms. If using the 1MHZ timer at best it would be 1e-6 seconds, which would be nice if I can get it to work using your suggestions.


Quote:
Originally Posted by Ether View Post


The default value in WPILib is to set up the FPGA to return the elapsed time between the most recent 2 counts (i.e. N=1). Have you ever changed that default value? If not, I can understand why you couldn't get it to give you a clean signal at high speeds.

I have not, for Java the function which configures the counters averager is not part of the API so I have to re-compile the WPIJ library. I have not gotten around to it yet, but it is on my to do list to play around with it after we bag the robot. Right now the default is 1 from the counter class.

Code:
this.m_counter.writeTimerConfig_AverageSize(1);
Any recommendation for a new averaging value?

Quote:
Originally Posted by Ether View Post


The speed signal comes from the sensor on the robot, not from the Driver Station. The only time the 20ms would come into play is when the driver changes the speed setpoint, which is typically a step change, not something that's continuously changing every 20ms.

Not correct, the code is set up so that the periodic functions (i.e autonomous periodic or teleop Periodic waits for a new driver station packet before executing. So any code within these blocks will only run once every new DriverStation packet which is 20ms. If you have code which samples your signal at 10ms, but then only drive your motor in the teleopPeriodic block, you are wasting half of your calulcations because they are not being used to command the motor. The 20ms comes into play anytime you have code within any of the periodic blocks. Its a Pitfall.

If you want to run your motor faster than 20ms, you must place the drive code in a different loop, thread, etc that does not wait for new DS packets.

Here is a snipit from the WPI Library showing the wait:

Code:
        if (nextPeriodReady()) {
          getWatchdog().feed();
          FRCControl.observeUserProgramTeleop();
          teleopPeriodic();
          didTeleopPeriodic = true;
        }

      }

      this.m_ds.waitForData();
    }
  }

  private boolean nextPeriodReady()
  {
    return this.m_ds.isNewControlData();
  }

Quote:
Originally Posted by Ether View Post


You've got that backwards. I'm not ignoring inertia, I'm depending on it. Inertia plays a critical role in making bang-bang speed control work cleanly. Bang-bang speed control likes a high inertia load, a fast control loop, and low phase lag in the speed feedback. Compared to the approach you are using, GetPeriod() gives a smaller phase lag for the same signal-to-noise. And bang-bang code is so simple that it's not a problem to run it at 10ms. It also has the fastest spinup and recovery time.

You are taking what I said out of context. The statement of inertia and bang-bang control were totally separate. I was simply stating that performing calculations at such a fast rate (i.e 10ms) may be unnecessary because there are other factors to be aware of... such as if your going to be calculating a signal every 10ms, make sure you run in a separate loop from the periodic functions, or else your control gets chopped to 20ms, and you loose half of your calculations instantaneously... secondly the inertia on your motor might not allow the motor to react within 10ms, so commanding it every 10ms is unnecessary. Essentially... when considering the physical constraints, it may reduce your need to calculate control signals at such high rates, and maybe slower rates are just as exceptable because your motor can only react in 50ms, or 100ms.


Quote:
Originally Posted by Ether View Post


GetPPCTimestamp(). It's not nanosecond but it's better than millisecond.

Not available on Java. The timer class in Java has getFPGATimeStamp() (returns ms) and getUsClock(), although the UsClock is deprecated I am not sure why.
__________________
Controls Engineer, Team 2168 - The Aluminum Falcons
[2016 Season] - World Championship Controls Award, District Controls Award, 3rd BlueBanner
-World Championship- #45 seed in Quals, World Championship Innovation in Controls Award - Curie
-NE Championship- #26 seed in Quals, winner(195,125,2168)
[2015 Season] - NE Championship Controls Award, 2nd Blue Banner
-NE Championship- #26 seed in Quals, NE Championship Innovation in Controls Award
-MA District Event- #17 seed in Quals, Winner(2168,3718,3146)
[2014 Season] - NE Championship Controls Award & Semi-finalists, District Controls Award, Creativity Award, & Finalists
-NE Championship- #36 seed in Quals, SemiFinalist(228,2168,3525), NE Championship Innovation in Controls Award
-RI District Event- #7 seed in Quals, Finalist(1519,2168,5163), Innovation in Controls Award
-Groton District Event- #9 seed in Quals, QuarterFinalist(2168, 125, 5112), Creativity Award
[2013 Season] - WPI Regional Winner - 1st Blue Banner

Last edited by NotInControl : 08-02-2013 at 11:55.
Reply With Quote
  #4   Spotlight this post!  
Unread 08-02-2013, 15:04
Ether's Avatar
Ether Ether is offline
systems engineer (retired)
no team
 
Join Date: Nov 2009
Rookie Year: 1969
Location: US
Posts: 8,043
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: Configure Timers


Quote:
Any recommendation for a new averaging value?
edited excerpt from one of my earlier posts:
...use only one channel of the encoder, and configure the FPGA to count only the rising edges of that channel and to report the period based on the elapsed time between the 126 most recent counts (i.e. set the FPGA averaging to 125 samples). You would use the GetPeriod() method of the Counter class to get the period. At 2300 rpm you should get single-digit rpm jitter (+/-3rpm) with this setup, and with only 1/4 of a rev lag instead of seven and a half revs. You could ask for speeds at a 10ms rate and get a fresh reading each time.

Quote:
If you want to run your motor faster than 20ms, you must place the drive code in a different loop, thread, etc that does not wait for new DS packets.
I thought that went without saying.


Quote:
You are taking what I said out of context.
Not intentionally. I was responding to what I thought you were saying. My point was: with enough load inertia and a fast enough execution cycle, you won't have the oscillations you seemed to be concerned about with bang-bang. Once you've got something working, you can slow the execution rate down if you like, but bang-bang is so short and simple it shouldn't be a problem to run it fast (unless there's excessive overhead in Java to do so).


Quote:
GetPPCTimestamp(). Not available on Java.
I'm not a Java guru. Can't you write a short assembly routine and ask the Java VM to run it using JNI?


Reply With Quote
  #5   Spotlight this post!  
Unread 08-02-2013, 17:06
sjspry sjspry is offline
Registered User
FRC #1984
Team Role: Programmer
 
Join Date: Jan 2011
Rookie Year: 2010
Location: Kansas
Posts: 125
sjspry has a spectacular aura aboutsjspry has a spectacular aura aboutsjspry has a spectacular aura about
Re: Configure Timers

I generally don't go and make my own spoon before I go to eat some soup.

That being said, I have tried to strongarm the Squawk VM running on the cRIO. An instance of Timer will handle execution of all of its TimerTasks. If you want, you can make instances of Thread and run them asynchronously from the main robot code. I would point out that you can't really guarantee the length of a timeslice unless you have ring 0 privileges. In this case, you could argue ring 0 privileges are JVM-level, but the JVM has a lot of overhead (compared to modern ones). I would say a timeslice of less than 15ms will be impossible to guarantee.

And everyone seems to bring up JNI. Has anyone who says that actually tried to use it? It'd be even harder on something like a FIRST-compliant cRIO, where you have huge restrictions on what you can do with the thing (not saying it'd be impossible, but more of a pain than usual).
Reply With Quote
  #6   Spotlight this post!  
Unread 08-02-2013, 17:15
Ether's Avatar
Ether Ether is offline
systems engineer (retired)
no team
 
Join Date: Nov 2009
Rookie Year: 1969
Location: US
Posts: 8,043
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: Configure Timers

Quote:
Originally Posted by sjspry View Post
That being said, I have tried to strongarm the Squawk VM running on the cRIO. An instance of Timer will handle execution of all of its TimerTasks. If you want, you can make instances of Thread and run them asynchronously from the main robot code. I would point out that you can't really guarantee the length of a timeslice unless you have ring 0 privileges. In this case, you could argue ring 0 privileges are JVM-level, but the JVM has a lot of overhead (compared to modern ones). I would say a timeslice of less than 15ms will be impossible to guarantee.
What is the context for the above? Are you just sharing some thoughts, or are you responding to something somebody posted in this thread?


Reply With Quote
  #7   Spotlight this post!  
Unread 08-02-2013, 17:34
sjspry sjspry is offline
Registered User
FRC #1984
Team Role: Programmer
 
Join Date: Jan 2011
Rookie Year: 2010
Location: Kansas
Posts: 125
sjspry has a spectacular aura aboutsjspry has a spectacular aura aboutsjspry has a spectacular aura about
Re: Configure Timers

I'm trying to say that this whole argument is basically futile because of the lack of control you have over the JVM and its scheduling. What control you do have you can not apply to the precision that is wanted.

Most tasks should be run by a Timer as TimerTasks. If you want to try to run something faster, use a Thread, but you will not be able to guarantee execution timing.
Reply With Quote
  #8   Spotlight this post!  
Unread 08-02-2013, 18:03
Ether's Avatar
Ether Ether is offline
systems engineer (retired)
no team
 
Join Date: Nov 2009
Rookie Year: 1969
Location: US
Posts: 8,043
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: Configure Timers

Quote:
Originally Posted by sjspry View Post
I'm trying to say that this whole argument
Which "argument" are you referring to? There are many different things being discussed here; many of them are not rendered pointless by your scheduling comment.


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 11:22.

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