UBC-Thunderbots / Software

Robot Soccer Playing AI
http://www.ubcthunderbots.ca
GNU Lesser General Public License v3.0
54 stars 110 forks source link

Define New Primitives and Primitive System #1415

Closed jonathanlew closed 4 years ago

jonathanlew commented 4 years ago

Description of the task

With the development of the new trajectory planner, genevaa drive, and new protobuf framework (#1386), we need to plan a new set of primitives to define the low-level actions that we need robots to be able to do now, and into the near future. Some goals include:

Acceptance criteria

Blocked By

Controller

garethellis0 commented 4 years ago

Currently, only one I had planned was updating the MovePrimitive to take the path to travel along as 3 polynomials; x, y, and theta.

MathewMacDougall commented 4 years ago

I think that's somewhat separate from this ticket. IMO this ticket covers any cleanup to the existing primitives (post removal of dead ones). Making the messages nicer / more descriptive, adding any information / functionality we've wanted (eg. kicking to DirectVelocity).

In terms of developing brand new primitives, IMO tickets for those should be created as we have a need for new primitives (YAGNI, no point theorizing about new primitives and making them before we need them, especially since we want simplicity).

@garethellis0 maybe make separate tickets for removing the old unused primitives. and another for the MovePrimitive refactor?

jonathanlew commented 4 years ago

The point of this planning ticket was to discuss and plan what we want to see in primitives before someone makes new tickets about removing/changing/adding primitives. Let's have that discussion first.

MathewMacDougall commented 4 years ago

Sounds good. Here's my thoughts

Removing Primitives Most of our primitives that exist in firmware either don't work, are unused, or both. The only ones we use are Move, Shoot, and Stop.

With all the existing and upcoming changes to Primitives and their surroundings (eg. the app layer, introduction of the profile planner and new controller), it doesn't really make sense to keep around primitives that we have no use in "upgrading". They're not needed for our current AI and so I don't think need to be kept around. If we want to use them again at some point in the future, we can re-design / implement them once all the new changes are in place.

New Primitives Some kind of pivoting and dribbling primitives are the only ones that come to mind that we might need in the future, and it's not clear whether or not we need entirely specialized primitives for those or if they can just be different uses of the move primitive with a different polynomial profile. Until the profile planner and path planner are done we won't really know enough to make issues.

garethellis0 commented 4 years ago

IMO:

I think the new move primitive will replace many older primitives like pivot while allowing for higher level motion planning that better takes into account the context of the action.

jonathanlew commented 4 years ago

Question: what's the difference between Move with autokick/chip on and Shoot

garethellis0 commented 4 years ago

Shoot does a major-minor axis control about the ball to take the shot, Move with autokick/chip on just moves to a point with the chipper/kicker enabled, and so would not be good at taking shots unless the robot was directly behind the ball already (and probably not even then).

jonathanlew commented 4 years ago

Sorry, what I mean is what can Shoot do that the new Move with trajectory planner with autokick on can't do?

jonathanlew commented 4 years ago

We need primitives for Robot Diagnostics: direct wheel, capacitor charge/float/discharge

MathewMacDougall commented 4 years ago

Sorry, what I mean is what can Shoot do that the new Move with trajectory planner with autokick on can't do?

I think we'd need to test to see if Move could replace shoot, I'm honestly not sure.

We need primitives for Robot Diagnostics: direct wheel, capacitor charge/float/discharge

Yea direct wheels and direct velocity will need to be updated. I don't think capacitor charge needs to be its own primitive, it probably makes sense to include with the direct primitives?

jonathanlew commented 4 years ago

Yea direct wheels and direct velocity will need to be updated. I don't think capacitor charge needs to be its own primitive, it probably makes sense to include with the direct primitives?

There's a lot of good discussion in this PR: #1422. We need 3 separate primitives to implement all the functionality:

  1. DirectWheels (wheels lf,rf,lb,rb) with charge/discharge/float, dribbling, and autokick/autochip
  2. DirectVelocity (x,y) with charge/discharge/float, dribbling, and autokick/autochip
  3. Direct kick/chip
MathewMacDougall commented 4 years ago

Ah so you're thinking manually firing the kicker / chipper should be it's own primitive? Other alternatives would be a KickType enum with AutoKick and ManualKick as it's possible values. Would Direct kick/chip only be for kicking (and I guess charge-state to support that), with no movement?

2 reasons we may want to combine it with DirectVelocity/Wheels

  1. Manually trigger a kick/chip while wheels are moving to measure EM noise and impact on encoders or other things like that. Manually triggering that is much safer than trying to trigger the breakbeam.
  2. Much less important use-case, manual kicking while moving may be useful for the xbox demo
jonathanlew commented 4 years ago

2 reasons we may want to combine it with DirectVelocity/Wheels

1. Manually trigger a kick/chip while wheels are moving to measure EM noise and impact on encoders or other things like that. Manually triggering that is much safer than trying to trigger the breakbeam.

2. Much less important use-case, manual kicking while moving may be useful for the xbox demo

Agreed so we have 5 primitives:

  1. Stop
  2. Move using Spline with dribbler flag (and autokick/autochip flag?)
  3. Shoot/Chip with major-minor axis control
  4. DirectWheels (wheels: lf,rf,lb,rb) with charge/discharge/float, dribbling, and autokick/autochip/kick/chip
  5. DirectVelocity (x,y) with charge/discharge/float, dribbling, and autokick/autochip/kick/chip
garethellis0 commented 4 years ago

I think it makes sense to combine both Direct primitives into some sort of test primitive, we could have a oneof field that is effectively either a x/y/theta velocity or a set of wheel speeds.

MathewMacDougall commented 4 years ago

That also makes a lot of sense, we're no longer limited by radio and can now use useful things like oneof which is a great idea.

MathewMacDougall commented 4 years ago

@EvanMorcom

EvanMorcom commented 4 years ago

I feel like we should brake out charge/discharge into their own things. Seems like they are lumped in with DirectVelocity for no concrete reason?

jonathanlew commented 4 years ago

Hm, the reasoning is to be able to test wheels movement, charge, kicking/chiping, dribbling simultaneously

garethellis0 commented 4 years ago

I think TestPrimitive might be a better name, or perhaps DirectRobotControl?

jonathanlew commented 4 years ago

RobotDiagnosticsPrimitive?

MathewMacDougall commented 4 years ago

I prefer DirectRobotControl or similar, because we would technically also use that primitive for things like xbox, so RobotDiagnostics is a bit over-specific.

jonathanlew commented 4 years ago

Currently, the move primitive with autokick/autochip enabled sends the ball at some arbitrary speed or distance and dribbles at an arbitrary speed

    if (params.extra_bits & 0x01)
        app_chicker_enableAutokick(chicker, (float)BALL_MAX_SPEED_METERS_PER_SECOND - 1);
    if (params.extra_bits & 0x02)
        app_dribbler_setSpeed(dribbler, 16000);
    if (params.extra_bits & 0x04)
        app_chicker_enableAutochip(chicker, 2); // this means auto chip 2 metres

I think we should have more control over the chick power and dribble speed. Thoughts on the following ideas?

  1. Add chick power and dribble speed to the move_primitive (will we have enough bytes leftover with the trajectory planner over radio? Do we care?)
  2. Add dribble speed to the move_primitive and remove autochick. We would use the shoot_primitive instead, since the shoot_primitive does have chick power
MathewMacDougall commented 4 years ago

I prefer suggestion 1 because we currently use the MovePrimitive to receive the ball and one-time kick, and I think switching to a shoot_primitive at the last second just to get kicking capability would be tricky / not work as well.

The question becomes how do we define kick vs chip power?

garethellis0 commented 4 years ago

we can have a oneof in the proto that is one of ChipCommand or KickCommand that holds the relevant parameters.

jonathanlew commented 4 years ago

We define kick power as speed in m/s and chip power in terms of distance in m, but that's theoretical. Who knows what the real world behaviour is

MathewMacDougall commented 4 years ago

We know what the real behavior is because we define and implement it ourselves?

jonathanlew commented 4 years ago

I don't think we calibrate it very well, so I wouldn't be confident that it actually reflects real world distance and speed

MathewMacDougall commented 4 years ago

Oh but at the very least that's what those values mean, so we know what reasonable values to send are. I think velocity isn't too bad but chipping definitely has some variability. Part of that comes with tuning and part is just with the inconsistency of real life, such as how far the ball is sitting in the chipper.

garethellis0 commented 4 years ago

@jonathanlew - you're correct, we need to actual to a study to see what the correlation is. Since this is likely to be specific to each robot some sort of calibration routine might be needed. Automating this would be tricky since it's hard to tell when the ball hits the ground from just the overhead camera, so it might just need to a manual process.

MathewMacDougall commented 4 years ago

I know the values are tuned (people manually gathered chip distance data to fit a polynomial and get a transfer function), but yes there is variability due to hardware. Especially for chipping, IMO there is more variability in the "setup" of the chip so an unsure if per-robot tuning is really worth it since we don't need to chip that accurately.

I think defining acceptable tolerances for each would also help guide this discussion, but is also something to ask elec about.

jonathanlew commented 4 years ago

we don't need to chip that accurately.

We'll never chip accurately with that attitude. We need to chip accurately to do chip passes and I think we should work on that next year.

MathewMacDougall commented 4 years ago

Yes but we don't know how much variation there is now, and how much variation we are willing to accept. That's what we should clarify.

garethellis0 commented 4 years ago

Both points are valid here. We should certainly try our best to chip accurately, but we should also decide how much regular effort and maintenance we're willing to trade off to do so, as it could be a consistent and significant burden.

I think a good place to start on this would be to:

Once we have this information, we can decide if we can get away with having a single model for all robots (the ideal scenario) and handle error in software, or whether we need to individually calibrate each robot (potentially a lot of work).