-
Notifications
You must be signed in to change notification settings - Fork 16
Add basic motion profiling #36
base: master
Are you sure you want to change the base?
Conversation
Note: The current stats for width/height/mass of the test bot are incorrect. I will get the right ones tomorrow, so just ignore this pull for now. As well as this, we can't actually use encoders on the test bot currently. |
robot/physics.py
Outdated
|
||
|
||
class PhysicsEngine(object): | ||
''' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm tempted to complain about your comment formatting here but this PR is so fantastic that I have a hard time doing that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you haha. I'll fix those quotes and check with pycodestyle as well.
TRAJECTORY_DIRECTORY = 'trajectories' | ||
|
||
|
||
trajectories = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a better way to do this then listing them in trajectory_generator
? This feels like something that would fit better in autonomous files. @ArchdukeTim may have better intuition on this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could read them in from a JSON? Pathfinder will also read in directly from a pathfinder binary created by he serialize
methods, and you can also do a CSV. I think the best alternative would be to store them all in a JSON file, but I don’t think it’s necessarily bad to do it here
self.right_follower.configureEncoder(self.r_encoder.get(), 360, self.WHEEL_DIAMETER) | ||
|
||
def is_following(self, trajectory_name): | ||
if self._current_trajectory == trajectory_name: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should change this to if self._current_trajectory is not None
so that passing in None
Before you’ve given it a trajectory to follow doesn’t return True. Edge case, but good practice
def is_following(self, trajectory_name): | ||
if self._current_trajectory == trajectory_name: | ||
return True | ||
return False |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personal preference, but wheneve you’re using an if condition to return true or false, just do return theCondition()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just good practice in general.
6*units.inch # wheel diameter | ||
) | ||
|
||
self.kEncoder = 360 / (0.5 * math.pi) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This value seems mighty mighty low.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those are some SMALL wheels.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think they're actually 6 inches, we can check to be sure @AndrewLester
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a good idea to make this a constant at any rate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's in feet. I think I just kept it that way for consistency, but I'm not sure. The 360 is low though, as I think it's the encoder counts per revolution which is normally higher.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that makes more sense, but then the encoder value still seems low I think
TRAJECTORY_DIRECTORY = 'trajectories' | ||
|
||
|
||
trajectories = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could read them in from a JSON? Pathfinder will also read in directly from a pathfinder binary created by he serialize
methods, and you can also do a CSV. I think the best alternative would be to store them all in a JSON file, but I don’t think it’s necessarily bad to do it here
robot/trajectory_generator.py
Outdated
generated_trajectories = _generate_trajectories() | ||
_write_trajectories(generated_trajectories) | ||
else: | ||
with open(os.path.join(os.path.dirname(__file__) + os.sep + TRAJECTORY_DIRECTORY, 'trajectories.pickle'), 'rb') as f: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
look at the docs for join
. There’s a better way to do this
@@ -1,3 +1,5 @@ | |||
pyfrc>=2018.0.0 | |||
robotpy-ctre>=2018.0.0 | |||
pynetworktables>=2018.0.0 | |||
pybind11>=2.2.2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Our favorite!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did this give you trouble in the past?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe we forgot to install it on the RIO last year and it took us a while to figure out what we'd done wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You shouldn't need to install this on the RIO. If you do, you're doing something wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@virtuald I'm likely thinking of a different package then.
Move along generated paths for autonomous | ||
""" | ||
# TODO FIND THE REAL VALUES | ||
WHEEL_DIAMETER = 0.5 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fairly sure the diameter is six inches but we can check
robot/physics.py
Outdated
@@ -0,0 +1,69 @@ | |||
# | |||
# See the notes for the other physics sample |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't think you want this
robot/physics.py
Outdated
|
||
def update_sim(self, hal_data, now, tm_diff): | ||
''' | ||
Called when the simulation parameters for the program need to be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah this is indented a little differently from how we normally do
robot/robot.py
Outdated
|
||
def createObjects(self): | ||
# Joysticks | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But why tho
robot/sim/config.json
Outdated
@@ -0,0 +1,18 @@ | |||
{ | |||
"pyfrc": { | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can probably get rid of this spacing dunno
If Tim is comfortable with this then I am too. I admittedly don't understand MP well enough to make actual substantive criticism on your methods. |
fef746f
to
b1bef71
Compare
robot/robot.py
Outdated
import wpilib.drive | ||
from robotpy_ext.common_drivers import navx |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update your robotpy-wpilib-utilties
robot/autonomous/charge.py
Outdated
from components import drive | ||
# from automations import | ||
# from magicbot import tunable | ||
from components import drive, trajectory_follower | ||
|
||
|
||
class Charge(AutonomousStateMachine): | ||
MODE_NAME = 'Charge' | ||
DEFAULT = True | ||
|
||
drive = drive.Drive |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you should change this to be drive: drive.Drive
for consistency
navx: navx.AHRS | ||
l_encoder: wpilib.Encoder | ||
r_encoder: wpilib.Encoder | ||
generated_trajectories: Dict |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dict
not Dict
. While this is a type hint, we're abusing it for our purposes, and the class that it is is dict
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's actually really cool. So magic bot looks at the type hint and uses it to match the object?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mhmm. Technically you could also do injectable = injectableType
but we thought it made more sense to use annotations
self.right_follower.configureEncoder(self.r_encoder.get(), 360, self.WHEEL_DIAMETER) | ||
|
||
def is_following(self, trajectory_name): | ||
return (self._current_trajectory is not None and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick: necessary parens
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What exactly do you mean by necessary parens? Do I not need the one surrounding both statements?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah you don’t need them. I meant to say unnecessary parens
|
||
def execute(self): | ||
if (self.left_follower.trajectory is None or self.right_follower.trajectory is None) or \ | ||
(self.left_follower.isFinished() and self.right_follower.isFinished()): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick: also technically necessary parens
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
*un
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lol I just saw he went the wrong way. Darn you autocorrect.
robot/physics.py
Outdated
|
||
self.drivetrain = tankmodel.TankModel.theory( | ||
motor_cfgs.MOTOR_CFG_CIM, # motor configuration | ||
110 * units.lbs, # robot mass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bump this up to 140-150 too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The kit robot only weighs 80ish pounds. Why 140-150?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh that’s right this is not the real robot. Ok just change it when you have a measurement
robot/robot.py
Outdated
@@ -76,4 +91,4 @@ def teleopPeriodic(self): | |||
|
|||
|
|||
if __name__ == '__main__': | |||
wpilib.run(Bot) | |||
wpilib.run(Bot, physics_enabled=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It took me a while to figure out why you had this, but then I checked the examples. Funnily enough, this doesn't actually do anything. Even if you set it to false 😂
robot/physics.py
Outdated
|
||
self.physics_controller = physics_controller | ||
|
||
# Change these parameters to fit your robot! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cut out all the comments that are only pertinent to example code.
robot/physics.py
Outdated
|
||
self.drivetrain = tankmodel.TankModel.theory( | ||
motor_cfgs.MOTOR_CFG_CIM, # motor configuration | ||
110 * units.lbs, # robot mass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know I'm really nitpicking hard here (and this is probably from the example you used) but pounds are a unit of weight, not mass.
0eb6cd0
to
975a463
Compare
Closes #35