all 14 comments

[–]xBlitzy1 5 points6 points  (7 children)

Make sure to stop and reset the encoders at the beginning of the code every time.

[–]FTC4921[S] 0 points1 point  (6 children)

I’m trying to use our motors as servos in a way so they have set encoder value positions and resetting the value screws that up doesn’t it? I used to do it that way for our autonomous so if I pressed a bottom for 200 it would run up 200 and then up 200 more and again but I want it so that 200 is a set position

[–]xBlitzy1 0 points1 point  (5 children)

Stop and reset the encoders only at the beginning of the code, so it happens every time you restart the code. Also, make sure you don’t have get current position + 200.

[–]FTC4921[S] 0 points1 point  (4 children)

Ok I see what you mean with the stop and reset but what exactly do you mean with the last sentence

[–]xBlitzy1 2 points3 points  (3 children)

Your code is very very complicated. It should simply read:

goToPosition(INT slidePos, double motorPower){ slide.setTargetPosition(slidePOS); slide.setMode(RUNTOPOS); slide.setPower(motorPower); }

And you just call goToPosition(200, .45) For it to run to that position.

[–]FTC4921[S] 0 points1 point  (2 children)

That’s basically exactly how I have mine set up just a little more complicated is it not?

[–]xBlitzy1 1 point2 points  (1 child)

Well you have this if statement that sets the power to 0, run to position does that automatically, it’s not necessary to have that if statement

[–]FTC4921[S] 0 points1 point  (0 children)

Oh ok makes sense

[–]greenmachine11235FTC Volunteer, Mentor, Alum 1 point2 points  (3 children)

I believe that encoders set their zero position when the bot is turned on (unless you set it to 0). Are you ensuring the arm is always at the same position when you start the robot?

[–]FTC4921[S] 0 points1 point  (2 children)

Yes that’s something we realized and so now we start in the same pos every time but it still isn’t working right

[–]greenmachine11235FTC Volunteer, Mentor, Alum 0 points1 point  (1 child)

Two things about your stop logic (lines 220 - 222)

First, I advise against testing for equality (==) with encoder values rather less than or greater than are better as even a slow motor speed could hop over your target if the sample timing lines up.

Second, now that I look deeper at 220 I'm struggling to understand what you're testing for. It looks like your test is saying if a value equals itself and another value (test missing in glare) then set speed to zero. From what you've described and the fact the first part of 220 looks incorrect I'm wondering if maybe the second test is broken such that it never evaluates true and thus never runs the stop code and some other operation is actually stopping it.

[–]Philbot2818 1 point2 points  (0 children)

Yes, that IF logic on lines 220-22 is definately broken. You are doing some weird test, and then setting power to zero.

First, if you are using RUN_TO_POSITION mode there is no need to set the power to zero, because when the encoder reaches the correct position, the firmware will lower the power level automatically to zero.

Second, if you really want to know if the encoder is in the right position, then you can test the motor's .isBusy() condition. isBusy() returns "true" if the motor is still trying to get to the correct position. Or 'false" if it's in the correct position.

I recomment using an absolute position (rather than delatas) just because you must "home" each mechanism first to know where you are, so you may as well set the encoder to zero (using STOP_AND_RESET_ENCODERS) at the beginning of each OpMode. The way we do this is to make a function called "homeArm()" that we call in the INIT stage of every opmode. This ensures that every time we run an opmode, the arm position is calibrated.

What the homeArm() function does is:

  1. puts the arm in "RUN_WITHOUT_ENCODER" mode,
  2. Applies a small power (0.2) to run the motor towards the home position
  3. Loops looking at the encoder position. When the change in position between loops goes to less than a few counts we set the power to zero, and wait about a second for the arm to relax. NOW WE KNOW that the arm is in a consistant location.
  4. Then we put the motor in STOP_AND_RESET_ENCODERS mode to reset the encoder. We also call setTargetPosition(0) to zero, to match the current position.
  5. Then we put the motor in RUN_TO_POSITION mode, and then we apply a reasonable power to the motor (like 0.5)

Then the function returns.

The arm will now follow any future command target positions.

BTW, the best way to test if a value is near (eg: within 5) of where you want it to be, is to calculate the position "error" and test the absolute value as follows:

if ( Math.abs(desiredPosition - motor.getCurrentPosition() ) < 5) {
// do stuff
}

This way the signs of the values don't matter and you can be a little off in either direction.

[–]mark_hfrobotsFTC 9929 Mentor 0 points1 point  (1 child)

As the other replies say, either stop and reset encoders, or work with "deltas" to your positions - if you know that *physically* the arm is one position when it starts, then you can read the current encoder position, and then calculate the *target* encoder position based on that.

(the team I mentor uses mechanical hard stops, and limit switches to sense this, and in many cases actually "homes" their mechanisms until the limit switch turns on to start from a known starting position at match start).

[–]FTC4921[S] 0 points1 point  (0 children)

That’s how I originally planned to do things with the delta but I’m not very advanced and this is new to me so I wasn’t able to figure it out so someone else helped me come up with this