FTC-12886 / FreightFrenzy-FtcRobotController

BSD 3-Clause Clear License
2 stars 2 forks source link

Improve Arm Control #6

Open jay-j opened 2 years ago

jay-j commented 2 years ago
jay-j commented 2 years ago

Implement repeatable (good precision) zeroing procedure. Mechanical limit switch? Initial hack look for edge under specific conditions using the existing magnetic encoder.

ToothbrushB commented 2 years ago
  • Change armLift to DcMotorEx class. Setup: set PIDF coefficients, RunMode RUN_TO_POSITION. Command with setTargetPosition() only (inherited from the DcMotor class).

I believe this could be useful, but I'm not sure if this is the most pressing issue. I still believe that just setting position and power works "good enough". It gets to the position accurately and quickly enough (accurately meaning the encoder value matches the desired position). If we have time (and we do have some), I think this would be helpful to competition, but more so as a learning exercise.

  • Profile the position commands. Using a "trapezoidal profiler" is standard in the robotics industry. One simple example here, in trap. Best supported by changing arm control to a state machine architecture.

I need to look into this some more. I kinda understand the principle (slowly increase and decrease velocity), but I need to look at the C code and port it over to Java. I think it would be useful to help with jerky movement if necessary.

Implement repeatable (good precision) zeroing procedure. Mechanical limit switch? Initial hack look for edge under specific conditions using the existing magnetic encoder.

We totally should and can use a limit switch. We have a few mechanical limit switches at the lab currently and just need to wire them up. As for using the encoder for detecting the edge, how would we implement that? Reset it when the driver presses the down button? Or do you mean by using the magnetic limit switch (reed switch with 1mm tolerance). In theory, the magnetic limit switch should work fine, but the way we have it mounted is not ideal and probably the cause of our issues with it.

jay-j commented 2 years ago

Usually in an incremental encoder + limit switch type system, there are many encoder values for which the limit switch will read as 'activated'. So instead of zeroing when the limit switch is active, the joint is moved slowly and the encoder is zeroed on the instant that the limit switch changes from 'off' to 'on'. This could be a technique to get better repeatability out of your existing hardware.

jay-j commented 2 years ago

What is going on in line 179? I am confused why duck mode has a different arm control paradigm than all the other heights.

jay-j commented 2 years ago

Do you have the source somewhere for setPower()? This API doc indicates that setPower has some affect in a position or speed control mode, but doesn't describe the math.

jay-j commented 2 years ago

Arm zeroPowerBehavior should be set to BRAKE.

ToothbrushB commented 2 years ago

Usually in an incremental encoder + limit switch type system, there are many encoder values for which the limit switch will read as 'activated'. So instead of zeroing when the limit switch is active, the joint is moved slowly and the encoder is zeroed on the instant that the limit switch changes from 'off' to 'on'. This could be a technique to get better repeatability out of your existing hardware.

I see, that makes more sense. It would be hard to find time to do that during the competition matches since we can't move motors during init and would waste time during autonomous or teleop. We might be able to get away with it in autonomous though since we don't use the entire time.

What is going on in line 179? I am confused why duck mode has a different arm control paradigm than all the other heights.

Because duck mode is activated while holding buttons instead of a toggle, we need to make sure that when the drivers nudge the arm, the arm doesn't go back to the original duck mode position. Therefore, we check how far the encoder position is from the desired position (the subtraction) to see if the driver has nudged the arm a little bit. If it appears the arm has been nudged, we will not move to the duck mode position. If the difference between the real position and the duck mode position is large (not nudged), we will move the arm to the duck mode position. Specifically, line 179 is just taking the difference between the desired encoder height and the real encoder height and taking the absolute value (so its always positive). The weird double negative is just to show that we are subtracting while keeping the original -650 value intact (which should actually be -680 to match line 181).

Arm zeroPowerBehavior should be set to BRAKE.

Fixed. Thanks for noticing.

Do you have the source somewhere for setPower()? This API doc indicates that setPower has some affect in a position or speed control mode, but doesn't describe the math.

Extracted source code can be found on this repository. At the top of the "tree", setPower() is first referenced in DcMotorSimple.java on line 84. If you follow the method calls/definitions, you find yourself at the LynxDcMotorController (the thing that the REV Robotics hubs use). In particular, the method internalSetMotorPower on line 524 shows the SDK scaling up the power to something that the expansion hub can read which is pretty much the only manipulation of the power other than absolute value. This is not very helpful at all, but it indicates all processing occurs on the expansion hub, whose code/firmware we cannot read. The expansion hub also appears to handle the PIDF control of setPosition too and probably everything else. I suppose this is to make reaction speeds faster and reduce transmission delay. We can still set the PIDF coefficients (and read them too), but unless we implement our own closed loop control (which might have a slower response time), we cannot tinker around too much with the controller.

jay-j commented 2 years ago

Seems like investigating zeroing will be our top item tomorrow. We could try watching for the sensor transition every time the arm is lowered to pickup a new gamepiece to get zeroing at no time cost.