Skip to content
This repository has been archived by the owner on Sep 26, 2023. It is now read-only.

Add basic motion profiling #36

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

AndrewLester
Copy link
Member

Closes #35

@AndrewLester
Copy link
Member Author

AndrewLester commented Jan 6, 2019

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):
'''
Copy link
Member

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

Copy link
Member Author

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 = {
Copy link
Member

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.

Copy link
Member

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:
Copy link
Member

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

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()

Copy link
Member

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)
Copy link
Member

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.

Copy link
Member

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.

Copy link
Member

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

Copy link
Member

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.

Copy link
Member Author

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.

Copy link
Member

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 = {
Copy link
Member

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

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:
Copy link
Member

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our favorite!

Copy link
Member

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?

Copy link
Member

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.

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.

Copy link
Member

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

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

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

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

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But why tho

@@ -0,0 +1,18 @@
{
"pyfrc": {

Copy link
Member

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

@ErikBoesen
Copy link
Member

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.

robot/robot.py Outdated
import wpilib.drive
from robotpy_ext.common_drivers import navx
Copy link
Member

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

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

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

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

Copy link
Member Author

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?

Copy link
Member

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: necessary parens

Copy link
Member Author

@AndrewLester AndrewLester Jan 7, 2019

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?

Copy link
Member

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()):
Copy link
Member

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

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*un

Copy link
Member

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

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

Copy link
Member

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?

Copy link
Member

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)
Copy link
Member

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!
Copy link
Member

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

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.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants