Announcement

Collapse
No announcement yet.

Encoder count maximum value

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • #46
    Originally posted by Alec View Post
    Be sure to call setMaxSpeed() and pass it the maximum attainable CPS of your particular brand/model of DC motor.
    If I understand their code correctly, why just NOT call setMaxSpeed() at all if you want maximum CPS? If you don't call setMaxSpeed, it is by default maximum, isn't it?

    Comment


    • #47
      Originally posted by Alec View Post
      Simply put, setMaxSpeed() defines the range of CPS values that the SDK will request the motor controller's PID to maintain. The SDK will map setPower() to the range 0 to (getMaxSpeed() * 0.8).

      There is a bug in the MR motor controller firmware that if the SDK requests a CPS that is not attainable by the motor, the motor controller firmware will randomly reverse power polarity. Your motor will be running full speed in one direction, and then suddenly be commanded to run full speed in the opposite direction. Needless to say, this is not very healthy for a motor under load. These sudden random reversals have nothing to do with the capacity of the motor controller's 4 byte encoder tick count register.

      Be sure to call setMaxSpeed() and pass it the maximum attainable CPS of your particular brand/model of DC motor.

      Tip: If you want your motor to run at a particular RPM (i.e. a particular CPS, say "cps") then the following code should do the trick:

      setMaxSpeed(cps / 0.8);
      setPower(1.0);

      But you have to be sure that the cps (RPM) that you request is attainable by the brand/model of your DC motor under load.
      There are only 2 parameters used by the MR motor controller firmware to control how fast the motor runs. The first is mode to select either, "power mode" or "run at constant speed" or "run to position", and the second is percentage of power to apply from -100 to + 100, or for the SDK -1 to +1. There is no "request a CPS", that is internal to the SDK which presumably translates into a power setting. If in power mode the power setting is +1 then the controller will apply full power to the motor but there is no monitoring by the firmware of how fast the motor is going or how many CPS it is outputting. That will vary depending on the motor. In constant speed mode the controller will take the power setting parameter and apply it to the motor (up to about 80%) and after a short period to enable the motor speed to stabilize for that power setting, will measure the number of encoder counts per time interval and then the controller will adjust the power setting as needed in order to maintain that number of encoder counts per time interval, thereby maintaining a constant speed.

      We have never seen any issues in testing or use that makes the motor randomly reverse but we will conduct a series of tests next week to try and recreate this. If anyone has details of how to reliably recreate this behavior please let us know via email ([email protected]).

      Comment


      • #48
        Originally posted by Modern Robotics Support View Post
        ... In constant speed mode the controller will take the power setting parameter and apply it to the motor (up to about 80%) and after a short period to enable the motor speed to stabilize for that power setting, will measure the number of encoder counts per time interval and then the controller will adjust the power setting as needed in order to maintain that number of encoder counts per time interval, thereby maintaining a constant speed.
        My NeveRest 20 motor has a maximum attainable CPS of 2800 with no load.

        When I call setMaxSpeed(2800) and then setPower(1.0), I get roughly 1800 CPS from the encoder (total scale factor of 0.64).

        So it seems that the SDK scales setPower(1.0) and passes a request of 0.8 power to the motor controller firmware. The firmware then scales that by 0.8 to arrive at a power of 0.64.

        The fimware measures the CPS at 0.64 power, which happens to be roughly 1800 CPS, and the firmware keeps the motor running at 1800 CPS.

        Since, in constant speed mode, the motor controller firmwarre measures the CPS at any given power setting, it seems to me that there is no need for a setMaxSpeed() method in the SDK.

        Further, since the firmware scales the power (for headroom), the SDK should simply pass the requested power in setPower() to the firmware without scaling it.

        Originally posted by Modern Robotics Support View Post
        We have never seen any issues in testing or use that makes the motor randomly reverse but we will conduct a series of tests next week to try and recreate this. If anyone has details of how to reliably recreate this behavior please let us know via email ([email protected]).
        We are in the middle qualifiers so teams need to know about these types of issues ASAP. To this end I've posted the following:

        Originally posted by Alec View Post
        Originally posted by 4634 Programmer View Post
        The internal PID in the MR controllers was reversing our flywheels after only about 1 minute and a half...
        I was able to reproduce this issue with the Core Device Discovery App. Using the Speed mode, the NeveRest 3.7 motor reverses direction within 2 minutes; reverses direction again within 2 minutes, and the reversals keep repeating and repeating within every 2 minutes.

        I could not reproduce the issue with NeveRest 20/40/60, which is odd because I thought the only difference between 3.7, 20, 40, and 60 is the gearbox (i.e. the four motors would have the same encoder and roughly the same CPS regardless of which gearbox is attached to the motor).
        Motor Controller Firmware ver: 2.0
        Device Discovery App ver: 2.0.3
        Motor selection: AndyMark
        Mode: Speed
        Power: 100
        I am also able to reproduce the random power polarity reversal with a NeveRest 20 motor, but not nearly as readily as with the NeveRest 3.7 motor.

        Comment


        • #49
          Andymark just sent me this update document.

          http://gearsinc.org/images/3.7NeveRe...TE12072016.pdf

          It shows that the new NR3.7 motors have a different encoder with lower CPR...

          Specifically 44.4 CP Revolution....

          This gives a theoretical maximum CPS of 1320.

          I'd probably recommend setting max Speed to 1300, and try to get a shooter working at no more than 80% full speed.

          Comment


          • #50
            Originally posted by Modern Robotics Support View Post
            There are only 2 parameters used by the MR motor controller firmware to control how fast the motor runs. The first is mode to select either, "power mode" or "run at constant speed" or "run to position", and the second is percentage of power to apply from -100 to + 100, or for the SDK -1 to +1. There is no "request a CPS", that is internal to the SDK which presumably translates into a power setting. If in power mode the power setting is +1 then the controller will apply full power to the motor but there is no monitoring by the firmware of how fast the motor is going or how many CPS it is outputting. That will vary depending on the motor. In constant speed mode the controller will take the power setting parameter and apply it to the motor (up to about 80%) and after a short period to enable the motor speed to stabilize for that power setting, will measure the number of encoder counts per time interval and then the controller will adjust the power setting as needed in order to maintain that number of encoder counts per time interval, thereby maintaining a constant speed.

            We have never seen any issues in testing or use that makes the motor randomly reverse but we will conduct a series of tests next week to try and recreate this. If anyone has details of how to reliably recreate this behavior please let us know via email ([email protected]).
            Try this...

            1) Find a motor/encoder that has a MAX CPS of 1200 (eg: a new Andymark NR3.7 motor)
            2) Tell it to run at 100% Speed (Using encoders), which will "expect" 4000 CPS.
            3) Wait two minutes for the Speed Error Integrator to wind up until the value (probably a 16 bit int) wraps.

            Comment


            • #51
              Originally posted by Philbot View Post
              Try this...

              1) Find a motor/encoder that has a MAX CPS of 1200 (eg: a new Andymark NR3.7 motor)
              2) Tell it to run at 100% Speed (Using encoders), which will "expect" 4000 CPS.
              3) Wait two minutes for the Speed Error Integrator to wind up until the value (probably a 16 bit int) wraps.
              But if it's only an issue with the 3.7s, why are we getting the same behavior with the non-3.7s?

              Comment


              • #52
                Originally posted by Alec View Post
                ... Be sure to call setMaxSpeed() and pass it the maximum attainable CPS of your particular brand/model of DC motor.

                Tip: If you want your motor to run at a particular RPM (i.e. a particular CPS, say "cps") then the following code should do the trick:

                setMaxSpeed(cps / 0.8);
                setPower(1.0);

                But you have to be sure that the cps (RPM) that you request is attainable by the brand/model of your DC motor under load.
                Apparently the encoderTicksPerSecond value (i.e. the CPS) passed to setMaxSpeed() has nothing whatsoever to do with the actual maximum encoder ticks per second of a motor.

                If you neeed to run a motor at a particular constant RPM:
                1. Using the Core Device Discovery App, configure your motor ports with the PID parameters for your brand/model of motor:
                  • For the TETRIX motor select "Tetrix"
                  • For the Matrix motors select "Matrix"
                  • For the NeveRest 20, 40, or 60 motor select "AndyMark"
                  • For the NeveRest 3.7 motor, select "Custom Configuration" and set P=128, I=40, D=192, Ratio=57, then click on "PID Set"

                2. Put the motor in RUN_USING_ENCODER run mode in your opmode
                3. Make sure you don't call setMaxSpeed(), or otherwise call setMaxSpeed(4000) (don't ask)
                4. Experiment with setPower() values until you get the RPMs that you need under load [or better yet write an opmode to find the setPower() value for the RPM you need (a great excercise for the students!)]

                Comment


                • #53
                  There is clearly significant confusion surrounding the setMaxSpeed() API, confusion for little current benefit. As a result, we are contemplating its removal in the next SDK update.

                  Thoughts and comments on that idea?

                  Comment


                  • #54
                    I recommend remove.

                    And for online documentation (including and especially the information associates with RUN_USING_ENCODERS) to become more complete and include the correct P, I, D and "ratio" values for each approved motor type. Or links to some always current MR documentation on the subject.

                    Inclusion of the resulting "headroom limits" for each motor/gearbox combination would also be handy. That is to say, if RUN_USING_ENCODERS operating with a correctly/default configured tetrix motor is maxed out at 0.8 "power" because the velocity servo control loop inside the MR motor controller needs the headroom, then can we document that someplace (along with the corresponding values for RUN_TO_POSITION, which seem like about 0.7 for Tetrix), for all the motor and gearbox combinations, using the aforementioned correct PID settings (if they end up being different from one another).

                    A lot of confusion seems to be stemming from where to put what kind of scaling factors and why. Since the motor control PID are buried down in the motor controller, along with some sort of "ratio" for encoders (??) then the SDK and documentation should all center around doing things that way.

                    At such point as the loop-times afforded the students become faster and more stable and independent of number of sensors and I2C stale-data-delayed stuff (see the numerous other threads on this subject), and it becomes more common for more teams to try to roll-their-own control laws, I would like to see the SDK perhaps include a clean set of methods for teaching & learning and implementing control law, possibly including bringing back an encoder-count-per-something scaler.

                    My $0.02

                    Coach Z

                    Comment


                    • #55
                      More than two more cents:

                      The 2.0 MR controllers allow firmware updates and PID,R coefficient changes over USB from the Device Discovery App, so what about some future SDK allows the students to configure motor controllers for different motors, or PID settings, from their code as opposed to needing to plug the module into a laptop? This could then allow clever things like altering servo-loops for DC motor powered heavy lift arms depending on whether they had grabbed something heavy or not. And SDK developers could have standard "correct" coefficients predefined. And kids could write code that looked like:

                      public void init() {
                      motor1 = hardwareMap.dcMotor.get("motorname");
                      etc
                      etc
                      motor1.setMotorType("Tetrix") /* sets all needed MR PID coefficients */
                      etc
                      etc for other motors of other types
                      }

                      public void loop() {

                      [Do whatever RUN_MODE and set Power stuff they want to do]

                      [Grab heavy Object, or lift other robot, or change robot's CG or anything else that might make one want to change a PID loop]

                      motor1.setPower(0.0);
                      motor1.setMotorCtrlCoeff(P, I, D, R, Direction);
                      While (motor1.CtrlStatus.get() == FALSE) {
                      /* do something while waiting for this MR controller to take new coefficients and be ready to run again */
                      }

                      [Do whatever they want to do with hoisting/moving this heavy object under PID control with encoders and such, without oscillation or undue following errors]

                      [then set the motor back to normal PID when done]
                      }


                      Most teams would only need to set the default motor types and never use the more advanced tricks of changing the coefficients. And since so many teams are probably using defaults Tetrix PID with andymark and other motors (after all what is this thread about?) just giving them a clean and clear way to define motor type while doing the usual motor method set ups will improve their lives. And there are not that many approved motors so the SDK Development team doesn't have to keep up with that many changes. If something crazy happens in the future like the oddball AM 3.7:1 motor with new sensor, a quick post here could tell all teams how to use setMotorCtrlCoeff in init() to work with it. And most teams could move on with their lives without PID integrator wind-up reversals and the other observations in this thread.

                      And while kids are learning PID, there'd be this simpler method of making PID changes so they get intuition for what the different coefficients do. Especially if the MR control law is implemented so some values could be set to zero and coaches could step kids through P, then PD, then PID.

                      Then advanced teams and kids could run amok doing whatever PID they wanted, down at the controller level and out of the way of all the sensor loop-delay-variation-stale-whatever-the-heck is going on.

                      And when and if there comes a time where sensor reading is stable and clean, those advanced teams can close the more interesting loops. Or just bury a wheel velocity servo of RUN_WITH_ENCODERS (ie running on the controller) inside the loop of a slow heading servo based on the gyro. (This BTW is what I suggested to my kids to do now, given the way things work today. Simple. Easy for them to understand. Not terribly dependent on sensor feedback times from the I2C gyro.)

                      And if MR, in the farther future, were to come out with motor controllers with I2C inputs in addition to encoder inputs, maybe the way to get really high performance closed loop things happening would be to allow motor controller loops to have other sensor inputs directly... Because if you want the kids doing truly real time controls, a chunky serial interface full of delays, waits, interruption and so on, may not be the best way to get there. Maybe fast loops with truly determinant loop times run on the motor controller processors, and slower stuff like "is heading greater than whatever" can poll sensors that are not attached to a sensor interface module but might alternatively be attached to motor controllers that needed faster access.

                      Basic teams still have simple. Advanced teams can go to town. In this hypothetical future world.

                      All this assumes there is some quick and stable way to talk to MR controllers' guts from the RC phone of course. But hey... if we're offering inputs, these are mine.

                      Coach Z

                      Comment


                      • #56
                        Originally posted by zain View Post
                        ...so what about some future SDK allows the students to configure motor controllers for different motors ... from their code as opposed to needing to plug the module into a laptop? ...
                        Coach Z
                        I think this is a very reasonable idea.

                        The dynamic updating of the PID coefficients in response to load, etc., is a little more complicated:
                        • The MR control loop is not a classic PID, nor is it publicly documented anywhere what it actually is.
                        • The PID parameters are stored in flash in the motor controller. As with all flash memory, the parameters can endure only a limited number of write cycles (measured in thousands, not millions) before wearing out.


                        Thanks for these thoughts.

                        Comment


                        • #57
                          Originally posted by FTC0417 View Post
                          I think this is a very reasonable idea.

                          The dynamic updating of the PID coefficients in response to load, etc., is a little more complicated:
                          • The MR control loop is not a classic PID, nor is it publicly documented anywhere what it actually is.
                          • The PID parameters are stored in flash in the motor controller. As with all flash memory, the parameters can endure only a limited number of write cycles (measured in thousands, not millions) before wearing out.


                          Thanks for these thoughts.
                          That's why we favor our own software PID control because we understand how ours works plus the fact that we need overall PID control instead of individual motor PID control. If we were to use the motor controller built-in PID, we wouldn't know how to tune the PID coefficients because it's not "classic" and not "documented".
                          There is only one thing we may be interested in using built-in PID is to do cascade PID control and use the built-in PID as the 2nd stage speed control. Regardless, we have added cascade PID control to our library (not yet tested) using software PID. But I am not looking forward to tuning a cascade PID controller with 2 sets of interacting PID constants. That's why using built-in PID as the 2nd stage would possibly free us from dealing with the 2nd stage.

                          Comment


                          • #58
                            I hadn't considered the issues with flash memory there. But if I may,

                            1. Surely there is some volatile memory in the controller with the ability to last a long time. And we are only talking about a few numbers. The coefficients don't *HAVE* to be in flash, if perhaps the way it works is for the controller to allow new (and I guess temporary) coefficients to be downloaded. Like in my hypothetical example above when a D.C. Motor sees a big change in the internal load it is trying to operate with.
                            2. All that would have to happen is somebody at MR document what P, I, D and R do. Because yeah, I'm sure there's more in there than an ordinary PID as it handles stall conditions and other factors gracefully and switches between a velocity servo loop and a position servo loop with the same coefficients in place. But I'm also pretty sure a simplified explanation would be good enough for teaching kids the basics, no?

                            Comment

                            Working...
                            X