Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Arm Control #6

Open
jay-j opened this issue Jan 26, 2022 · 8 comments
Open

Improve Arm Control #6

jay-j opened this issue Jan 26, 2022 · 8 comments
Assignees
Labels
enhancement New feature or request

Comments

@jay-j
Copy link

jay-j commented Jan 26, 2022

  • Change armLift to DcMotorEx class. Setup: set PIDF coefficients, RunMode RUN_TO_POSITION. Command with setTargetPosition() only (inherited from the DcMotor class).
  • 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.
@jay-j
Copy link
Author

jay-j commented Jan 26, 2022

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

@ToothbrushB
Copy link
Collaborator

  • 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.

@ToothbrushB ToothbrushB self-assigned this Jan 26, 2022
@ToothbrushB ToothbrushB added the enhancement New feature or request label Jan 26, 2022
@jay-j
Copy link
Author

jay-j commented Jan 26, 2022

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
Copy link
Author

jay-j commented Jan 26, 2022

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
Copy link
Author

jay-j commented Jan 26, 2022

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
Copy link
Author

jay-j commented Jan 26, 2022

Arm zeroPowerBehavior should be set to BRAKE.

@ToothbrushB
Copy link
Collaborator

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
Copy link
Author

jay-j commented Jan 26, 2022

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.

@ToothbrushB ToothbrushB linked a pull request Jan 27, 2022 that will close this issue
@ToothbrushB ToothbrushB removed a link to a pull request Jan 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants