WPIRoboticsEngineering / RBE1001Lib

A library to support introduction to robotics engineering.
MIT License
4 stars 4 forks source link

Create Motor class #6

Closed madhephaestus closed 4 years ago

madhephaestus commented 4 years ago

From @gcl8a regarding @bradamiller W.r.t. library classes, absolutely. In my opinion, the functionality needs to be wrapped into classes with similar functionality to the VEX libraries:

    Motor::SetEffort() or SetTargetSpeed() [depending on what we’re doing for PID control of motors... @bradamiller ?]
    Motor::CalcSpeed()
madhephaestus commented 4 years ago

What other API's should this motor class have?

madhephaestus commented 4 years ago

I went ahead and added the API's discussed already and tested the stack with a simple p-controller to ensure there was no timing or thread/interrupt interactions. THere was an issue using the PCNT module from inside an interrupt, but that was easily worked around by not using a timer interrupt and instead using a thread and vTaskDelayUntil as the fixed frequency timing. This worked VERY well and may be worth swapping out the timer in the rangefinder for this method.

With the fixed time loop running interrupt driven from within the library, the user can just use the object like any other statically declared object in their code. the Fixed frequency thread makes sure the encoders are read at a regular time interval, and so the velocity is computed with a known and fixed time base.

To see what i have so far, look at the motor Test in Examples, and the Motor.cpp in the src directory.

gcl8a commented 4 years ago

I can split things into multiple issues in the future — just getting thoughts out now. Apologies for breaking github best practices…

I think the API should mimic to some extent what they see in the VEX core. Not because it needs to mimic it, per se, but because that’s the level that we teach the course at. So…

Motor::SetSpeed() Motor::GetSpeed() Motor::GetPosition() wouldn’t hurt, though we might not use it since we’re using an RC servo for the part that requires position control.

Not sure if they’ll use SetEffort() directly, but to me it always reads better with SetEffortPercent, which ranges from 0 - 100, instead of 0 - 1. I suppose overload it with one version that takes ranges from -100 to 100 and one that takes 0 - 100 and a direction? Easy enough to do and we can hide whatever we want later. The units business of VEX is cool (though sometimes cumbersome) — I don’t think it’s called for here, though. Easier to just incorporate into the function names, eg, GetSpeedDPS().

Is PCNT related to the encoders? I don’t see why it was a problem. [Side note: Paradoxically, all this is fine and well for 1001, where they should get an API with a lot of the details hidden, but the code demonstrates the difficulty of using an RTOS in the 2000s: we end up with this odd mix of RTOS and “Arduino” code and we’re somewhat forced to give the students too much, since expecting them to anything meaningful at that level is unrealistic. As a counterexample, it is quite straightforward to have them set up a timer on an AVR/ARM chip (even if the gory details are left to 2049). We should make a legit push for RBE 40XX, RTOS for Robotics.]

Let’s add integral control to Motor::loop(). A simple, constrained sum should do fine. Derivative control can also be added, but that can be hard to tune for velocity.

This is kind of a no-no:

Motor * Motor::list[MAX_POSSIBLE_MOTORS] = { NULL, NULL, NULL, NULL };

A #defined size, but fixed initialization. If someone changes MAX_POSSIBLE_MOTORS, but doesn’t see to change the initialization, things could go belly up fast.

Greg

On May 31, 2020, at 6:08 PM, Kevin Harrington notifications@github.com wrote:

I went ahead and added the API's discussed already and tested the stack with a simple p-controller to ensure there was no timing or thread/interrupt interactions. THere was an issue using the PCNT module from inside an interrupt, but that was easily worked around by not using a timer interrupt and instead using a thread and vTaskDelayUntil as the fixed frequency timing. This worked VERY well and may be worth swapping out the timer in the rangefinder for this method.

With the fixed time loop running interrupt driven from within the library, the user can just use the object like any other statically declared object in their code. the Fixed frequency thread makes sure the encoders are read at a regular time interval, and so the velocity is computed with a known and fixed time base.

To see what i have so far, look at the motor Test in Examples, and the Motor.cpp in the src directory.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/WPIRoboticsEngineering/RBE1001Lib/issues/6#issuecomment-636537571, or unsubscribe https://github.com/notifications/unsubscribe-auth/AF5JK5AH2GXMGZMTZV62WUDRULIOJANCNFSM4NPF4H6Q.

madhephaestus commented 4 years ago

cool, how about the closed loop control API? SetSetpoint(set) or SetSetpointWithTime(set, time)

gcl8a commented 4 years ago

What’s the “WithTime” referring to? Is this speed or position control?

On Jun 1, 2020, at 9:04 AM, Kevin Harrington notifications@github.com wrote:

cool, how about the closed loop control API? SetSetpoint(set) or SetSetpointWithTime(set, time)

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/WPIRoboticsEngineering/RBE1001Lib/issues/6#issuecomment-636849337, or unsubscribe https://github.com/notifications/unsubscribe-auth/AF5JK5BS2Y7L6LWZVTSTI6LRUORPLANCNFSM4NPF4H6Q.

madhephaestus commented 4 years ago

position control over time, interpolation of setpoints at the 1khz loop rate. The other option is a velocity controller and a stateful controller that switched from position mode to velocity control mode. The position interpolation is easy, the velocity controller is a bit more work but doable also.

madhephaestus commented 4 years ago

also, is this API in engineering usints, or hardware units (ticks and PWM percents)?

gcl8a commented 4 years ago

I dunno’ that we’ll even really need position control, so certainly don’t do anything complicated at the moment.

On Jun 1, 2020, at 9:12 AM, Kevin Harrington notifications@github.com wrote:

position control over time, interpolation of setpoints at the 1khz loop rate. The other option is a velocity controller and a stateful controller that switched from position mode to velocity control mode. The position interpolation is easy, the velocity controller is a bit more work but doable also.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/WPIRoboticsEngineering/RBE1001Lib/issues/6#issuecomment-636852769, or unsubscribe https://github.com/notifications/unsubscribe-auth/AF5JK5D3WPW2ND6FGABN67DRUOSKLANCNFSM4NPF4H6Q.

gcl8a commented 4 years ago

Speed in degrees per second.

Position in degrees.

Effort in percent full power (technically, full voltage, ie, percent duty cycle).

On Jun 1, 2020, at 9:13 AM, Kevin Harrington notifications@github.com wrote:

also, is this API in engineering usints, or hardware units (ticks and PWM percents)?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/WPIRoboticsEngineering/RBE1001Lib/issues/6#issuecomment-636853378, or unsubscribe https://github.com/notifications/unsubscribe-auth/AF5JK5BZNZIVIRE3F3M2AATRUOSOVANCNFSM4NPF4H6Q.

madhephaestus commented 4 years ago

the PWM api takes "percents" as floating point unit vector from 0-1.0. I had effort as a -1.0 to 1.0 value, is that ok, of should it be changed?

gcl8a commented 4 years ago

Of course, it doesn’t really matter, but my preference is percent: 0 - 100. It gives a more “human readable” value.

So, just add a function:

void SetEffortPercent(float percent) {SetEffort(percent * 0.01;}

then we have both. (In general, we don’t want to have the number of methods explode, but this cheap “overload” is fine.)

On Jun 1, 2020, at 9:45 AM, Kevin Harrington notifications@github.com wrote:

the PWM api takes "percents" as floating point unit vector from 0-1.0. I had effort as a -1.0 to 1.0 value, is that ok, of should it be changed?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/WPIRoboticsEngineering/RBE1001Lib/issues/6#issuecomment-636869702, or unsubscribe https://github.com/notifications/unsubscribe-auth/AF5JK5FJ5CUHFVUHYVUJRWDRUOWI7ANCNFSM4NPF4H6Q.