Announcement

Collapse
No announcement yet.

Stall Detection in Turning

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

  • Stall Detection in Turning

    For some reason, the stall detection code doesn't seem to be working. The robot just turns for maybe less than 3 degrees then it moves on to the next task.

    Code:
    private double stallStartTime = 0.0;
    private int prevLeftPos = 0;
    private int prevRightPos = 0;
    
    while (!pidControlTurn.isOnTarget()) {
                double currTime = HalUtil.getCurrentTime();
                int currLeftPos = leftMotor.getCurrentPosition();
                int currRightPos = rightMotor.getCurrentPosition();
                double outputPower = pidControlTurn.getPowerOutput();
                leftMotor.setPower(outputPower);
                rightMotor.setPower(-outputPower);
                /*if (currLeftPos != prevLeftPos || currRightPos != prevRightPos)
                {
                    stallStartTime = currTime;
                    prevLeftPos = currLeftPos;
                    prevRightPos = currRightPos;
                }
                else if (currTime > stallStartTime + 0.5)
                {
                    // The motors are stalled for more than 0.5 seconds.
                    break;
                }*/
                pidControlTurn.displayPidInfo(0);
                opMode.idle();
            }

  • #2
    Can you give more details on your issue? What degrees did you intend to turn. The code you posted has the "stall detection code" commented out. What was the real code you were running?

    Comment


    • #3
      I started using the commented out part and then sometimes the robot just doesn't turn and immediately moves to the next step. Since I have stall detection in both driving and turning and my code sequence is to drive then turn, the robot usually barely drives and then suddenly turns with massive oscillations. Some other runs were that when it finished driving, it turned maybe around 3 degrees before driving forward again. These tests have been ran without stall detection on the driving method. The stall detection code is present and uncommented on the turning method.

      Comment


      • #4
        I need to see the whole code. Would you push your code to GitHub?

        Comment


        • #5
          I'll push it to GitHub but then it'll be commented out as I'm just programming my team's autonomous at the moment. https://github.com/lockdown8564/Lock...DriveBase.java

          Comment


          • #6
            I am not sure how the tuned TRClib pid control performs, but I know that with the motor controller PID control, depending on the turn speed, it can take a while to get any encoder count increase - tenths of seconds for small turns at small speeds.
            I see that you reset the stall counter on any change in encoder value. You may want to have a threshold, as moving a small handful of counts (out of 1120 for NeveRest 40 motors) over the course of 0.5s is essentially stalled.

            Comment


            • #7
              Originally posted by FTC7253 View Post
              I am not sure how the tuned TRClib pid control performs, but I know that with the motor controller PID control, depending on the turn speed, it can take a while to get any encoder count increase - tenths of seconds for small turns at small speeds.
              I see that you reset the stall counter on any change in encoder value. You may want to have a threshold, as moving a small handful of counts (out of 1120 for NeveRest 40 motors) over the course of 0.5s is essentially stalled.
              Stall detection will consider "stalled" when the encoders don't change for half a second. So in order to break out of the while loop, it must considered it stalled. Half a second is a LONG time for robot control. Unless you are turning a really small angle like 5 or 10 degrees in which case if it doesn't move for half a second, it probably won't move in any case. If you use a threshold:
              Code:
              if (Math.abs(currLeftPos - prevLeftPos) >= THRESHOLD || Math.abs(currRightPost - prevRightPos) >= THRESHOLD)
              {
                  //reset stall counter
              }
              else if (currTime > stallStartTime + 0.5)
              {
                  break;
              }
              That means you are NOT resetting the stall counter even if is moving slightly (less than THRESHOLD). Wouldn't it be worse? If it breaks out of the while loop prematurely, it really means the encoder values didn't change for half a second.
              I don't see anything wrong with the code off hand. Would you do two things:
              Code:
              if (currLeftPos != prevLeftPos || currRightPost != prevRightPos)
              {
                  stallStartTime = currTime;
                  prevLeftPos = currLeftPos;
                  prevRightPos = currRightPos;
              }
              else if (currTime > stallStartTime + 0.5)
              {
                  Log.i("TrcDbg", "Stall detected!!!");
                  break;
              }
              I want to see if it really detected a stall. If it does, change the stall timeout to 1 second instead of 0.5 and see if it fairs better.
              Before you do all these, let me ask a question: with the stall detection code commented out, did the drive and turn worked?

              Comment


              • #8
                The threshold helps when it near stall. We see cases where we need to make a small correction, and the speed from the PID is just enough to get the wheels creeping very slowly. We can't wait that long, so if we are moving less some number of CPS, we consider the precision not worth the time. I don't want to wait a second for 10 counts (~0.1 inches of wheel progression for our geometry). We combine the stall threshold with a min power and see decent fairly quick results.
                The threshold also helps if we are pressing against the wall/beacon, where the deflection and minor slip allow the counts to creep up. For these cases, it doesn't make sense to reset the stall counter every time we see single count increase.
                We have two stall cases that we handle separately:
                1)Decent power is being supplied, but corresponding motion is not occurring. We could be against an obstacle (wall, bot, etc.). Here we bail pretty quickly.
                2)Low power is being commanded by the PID to make fine tuning adjustments. We give this a little longer, and also apply a min power to overcome friction to get things moving.

                Comment


                • #9
                  Originally posted by FTC7253 View Post
                  The threshold helps when it near stall. We see cases where we need to make a small correction, and the speed from the PID is just enough to get the wheels creeping very slowly. We can't wait that long, so if we are moving less some number of CPS, we consider the precision not worth the time. I don't want to wait a second for 10 counts (~0.1 inches of wheel progression for our geometry). We combine the stall threshold with a min power and see decent fairly quick results.
                  The threshold also helps if we are pressing against the wall/beacon, where the deflection and minor slip allow the counts to creep up. For these cases, it doesn't make sense to reset the stall counter every time we see single count increase.
                  We have two stall cases that we handle separately:
                  1)Decent power is being supplied, but corresponding motion is not occurring. We could be against an obstacle (wall, bot, etc.). Here we bail pretty quickly.
                  2)Low power is being commanded by the PID to make fine tuning adjustments. We give this a little longer, and also apply a min power to overcome friction to get things moving.
                  If it takes too long to go to the target because it's moving too slowly, it means the PID constants are not tuned correctly. Besides, half second is a reasonable time for it to "try" getting there. In our case, we usually need a certain accuracy, so it will at least try. Regarding the scenario of being stuck against an obstacle and the wheels are still turning, I thought about doing a threshold before but decided against it because by doing so sacrifice the accuracy in other scenarios. Besides, what is a good threshold? The robot can be stuck with the wheels spinning at moderate speed, so it's a red herring to decide the right amount of threshold. I think we would add an absolute timeout as a safeguard. The absolute timeout was our old algorithm, we took it out for the stall timeout code but I plan to put that back as a safeguard.

                  Comment


                  • #10
                    The drive and turn methods worked without the stall detection. The turn just stalled without breaking the while loop. I'll test this out later this afternoon with the suggested fixes. I'm just testing it out with like 45 degrees.

                    Comment


                    • #11
                      Are you saying the drive and turn methods worked without the stall detection and once you uncommented the stall detection code, it hung in the while loop without breaking out? For the stall detection code not breaking out of the loop, it means at least one wheel is turning. Doesn't it mean the robot was still turning?

                      Comment


                      • #12
                        I mean like when I uncommented both the stall detection in the drive method and the spin method, the robot wouldn't execute the drive and immediately starts turning. When I commented the stall detection in the drive, it worked because the robot wasn't pushing against anything and it correctly goes to the distance that I specify. When I had both methods without stall detection, that was just for autonomous programming and the robot hung when in the process of turning because it was trying to go to a certain amount of degrees but had only a power of 0.1. The error was around like 5 degrees in some cases and then worse like 10 in other tests for turning.

                        Comment


                        • #13
                          Originally posted by FTC8564 View Post
                          I mean like when I uncommented both the stall detection in the drive method and the spin method, the robot wouldn't execute the drive and immediately starts turning. When I commented the stall detection in the drive, it worked because the robot wasn't pushing against anything and it correctly goes to the distance that I specify. When I had both methods without stall detection, that was just for autonomous programming and the robot hung when in the process of turning because it was trying to go to a certain amount of degrees but had only a power of 0.1. The error was around like 5 degrees in some cases and then worse like 10 in other tests for turning.
                          Okay, now that I know what the exact symptom was, I probably know what's going on. Would you add a line of code before the while loop in both drivePID and spinPID?
                          Code:
                          stallStartTime = HalUtil.getCurrentTime();
                          while (...);
                          Basically, if stallStartTime is not initialized correct and you just first starting out, the wheels have not moved yet. Then it will take that as timed out and break out of the loop.

                          Comment


                          • #14
                            It works a lot better now! Thanks!

                            Comment


                            • #15
                              Another (probably inferior) way to do stall detection would be to monitor the battery voltage. At least for us, the drive chain stalling causes the voltage to drop to ~10.6v

                              Comment

                              Working...
                              X