wpilibsuite / allwpilib

Official Repository of WPILibJ and WPILibC
https://wpilib.org/
Other
1.09k stars 611 forks source link

Examples consolidation #4836

Open Starlight220 opened 1 year ago

Starlight220 commented 1 year ago

There are too many example projects, which causes duplicates as well as the list being too long to be useful. The tags are also not organized enough to be useful. We should consolidate the example projects and change the tags to actually be useful. The list on frc-docs is outdated anyway.

Currently, we have these examples: (RLId examples are in italics) - _GettingStarted_: differential drive, timed auto, Xbox arcade. - TankDrive: differential drive, double-Joystick tank. - TankDriveXboxController: same as above, with split Xbox tank. - ArcadeDrive: differential drive, single-Joystick arcade. - ArcadeDriveXboxController: same as above, with split Xbox arcade. - _MecanumDrive_: mecanum drive, single-Joystick arcade. - _PDPCAN_: PDP telemetry monitoring. - Solenoids: simple hardware example of solenoids. - Encoder: simple hardware example of a quadrature encoder. - _EventLoop_: flywheel PID+FF using BooleanEvents (not command-based). - Relay: simple hardware example of a relay. - Ultrasonic: differential drive P control based on an AnalogInput *(this example naming is rather confusing, as it doesn't use the Ultrasonic class!)* - UltrasonicPID: exact same as above, just using the PIDController class rather than manually multiplying by `kP`. - PotentiometerPID: similar to above. - _ElevatorTrapezoidProfile_: trapezoid profile with a smart motor controller. - _ElevatorProfiledPID_: ProfiledPID. - Gyro: differential drive, single-Joystick arcade drive with analog gyro `kP` for driving straight. - GyroMecanum: field-oriented single-Joystick arcade mecanum drive. - HIDRumble: Xbox rumble. - _Mechanism2d_: jointed arm on an elevator, put to Mechanism2d. - MotorControl: simple hardware example of a motor controller. - MotorControlEncoder: same as above, with encoder telemetry. - Gearsbot: traditional command-based robot with autonomous, differential drive with Xbox tank drive, PIDSubsystem elevator, PIDSubsystem wrist, timed control of a claw. - _QuickVision_: one-liner publishing of a camera to CameraServer. - _IntermediateVision_: basic vision processing with opencv on another thread. - AxisCamera: same as IntermediateVision, just with an Axis camera. - Shuffleboard: Shuffleboard API. - _HatchbotTraditional_: traditional command-based robot with autonomous, differential drive with split Xbox arcade drive, hatch subsystem actuated by a double solenoid. - _HatchbotInline_: inline command-based robot with autonomous, differential drive with split Xbox arcade drive, hatch subsystem actuated by a double solenoid. - RapidReactCommandBot: inline command-based robot with autonomous, differential drive with split Xbox arcade drive, intake, PID+FF flywheel. - _SelectCommand_: use of SelectCommand to choose between PrintCommands - _SchedulerEventLogging_: command logging with random commands, and Shuffleboard markers. - _Frisbeebot_: inline command-based robot with autonomous, PIDSubsystem flywheel, differential drive with split Xbox arcade drive. - _GyroDriveComands_: mixed inline/traditional command-based, differential drive with split PS4 arcade drive, heading control with PIDCommand and ProfiledPIDCommand. - Swervebot: swerve odometry/kinematics. - Mecanumbot: mecanum odometry/kinematics. - DifferentialDrivebot: differential drive odometry/kinematics. - _RamseteCommand_: command-based differential drive path following with RamseteCommand. - DutyCycleEncoder: simple hardware example of a duty cycle encoder. - DutyCycleInput: simple hardware example of a duty cycle input. - _AddressableLED_: simple example of addressable LEDs, with a unit test. - DMA: simple hardware example of a DMA usage. - _Armbot_: command-based robot, PID+FF ProfiledPIDSubsystem arm, differential drive with split Xbox arcade drive. - _ArmbotOffboard_: same as above, with smart motor controller ProfiledPIDSubsystem arm. - _DriveDistanceOffboard_: command-based differential drive with smart motor controller TrapezoidProfileCommand and split Xbox arcade drive. - MecanumControllerCommand: same as RamseteCommand for mecanum. - _RamseteController_: non-command-based differential drive Ramsete path following. - _StateSpaceFlywheel_/_SysId_: state-space flywheel control with different methods of model construction. - StateSpaceElevator/Arm: elevator/arm with state space and trapezoid profiles. - SimpleDifferenetialDriveSimulation: non-command-based simulation of differential drive. - _StateSpaceDifferentialDriveSimulation_: command-based version of above, with RamseteCommand path following. - _Arm_/_ElevatorSimulation_: non-command-based arm/elevator simulation. - _UnitTest_: non-command-based intake with unit testing. - Differential/Mecanum/SwerveDrivePoseEstimator: differential/mecanum/swerve drive pose estimator. - RomiReference: Romi command-based. - DigitalCommunication: simple hardware example of using digital outputs to send data to an arduino or such. - I2CCommunication: simple hardware example of an I2C device such as an arduino.

I have multiple suggestions:

More ideas are welcome.

virtuald commented 1 year ago

I'm -1 on combining projects (which spans most of your ideas). Combining projects is going to make it harder for newer programmers to understand what exactly is needed for a particular task. IMHO, most examples for new programmers should be concise and exhibit how to do a single thing.

I think grouping the projects better will make navigating the project list easier and support more examples.

Starlight220 commented 1 year ago

Currently there is a lot of repetition in the projects. That isn't good.

IMHO, most examples for new programmers should be concise and exhibit how to do a single thing.

This isn't practical, especially for more complicated tasks that require more structure (or anything command-based). It also doesn't allow testing (which we've noted is a problem multiple times).

ThadHouse commented 1 year ago

I agree with Dustin on combining examples. Its going to make things worse for many of the things we have examples for.

The big issues is we have 2 types of examples. HW examples, and program structure examples. Maybe we should split those into multiple example types, that get showed in different lists in VS Code. HW examples don't make sense to be fully structured programs, and really should just be a single point on how to use an API.

virtuald commented 1 year ago

It also doesn't allow testing (which we've noted is a problem multiple times)

RobotPy has a testing methodology that allows testing full robot programs. It could be easily adapted to Java/C++ and alleviate some of that.

Starlight220 commented 1 year ago

RobotPy has a testing methodology that allows testing full robot programs. It could be easily adapted to Java/C++ and alleviate some of that.

Testing full robot programs isn't the problem. It's more that those examples don't have any logic or anything that can/should be tested.


@ThadHouse where do you draw the line between HW examples and structure examples? For example, what would the AddressableLED example be? What about the Mechanism2d one? What about MecanumBot?

What format do you suggest HW examples be in? Robot-only programs (=the current situation)? Something else?

Besides, showing the context in which an API is used is also important; a bunch of method calls randomly thrown together isn't really helpful.

Additionally, "a single point showing how to use an API" might be more effective as an frc-docs article than an example project.


I think the actual question we're implicitly debating here is "what's the purpose of the example projects?"

truher commented 1 year ago

Hi, just want to indicate my support for @virtuald here: having a large number of small example projects is much better than writing more frc-docs articles.

i agree with @Starlight220 that the question is really about purpose, and i'd propose an answer, which is that the purpose is pedagogical, and that depending on the topic being taught by an example, the size of the "minimum reproducible example" might be small (demonstrate the LED's) or large (demonstrate swerve pose estimation). the most important thing is that an example runs so a student can poke at it.

so i'd suggest going in the other direction: more examples, not fewer, particularly of things that are important but not well represented (e.g. writing simulation code against websockets, or unit testing sequential operations with simulated driver input). maybe if there were a wishlist, some teams would step up to fill it out.

Starlight220 commented 1 year ago

As there isn't a consensus as for the examples themselves, and it's too late for any changes in allwpilib structure or vscode, I think a first step in the meantime would be organizing the tags. Having a proper tag system would be helpful in seeing the distribution of what examples we have, ease of finding examples that do something specific, and so on.

Currently, these are the tags we have and how many times they are present. 18 "Sensors" 17 "Joystick" 14 "Actuators" 13 "Digital" 11 "State Space" 10 "PID" 7 "Getting Started with Java" 7 "Complete List" 7 "Command-based" 6 "Vision" 6 "Drivetrain" 5 "Robot and Motor" 4 "Simulation" 4 "Complete Robot" 3 "Trajectory" 3 "Shuffleboard" 3 "Pose" 3 "Path following" 3 "Odometry" 3 "Motion Profile" 3 "Mechanism2d" 3 "Filter" 3 "Elevator" 3 "Analog" 2 "Ultrasonic" 2 "Swerve" 2 "Safety" 2 "Physics" 2 "MecanumBot" 2 "Mecanum" 2 "Lambdas" 2 "Flywheel" 2 "Differential Drive" 2 "Arm" 1 "Unit Testing" 1 "Testing" 1 "SwerveControllerCommand" 1 "SwerveBot" 1 "StateSpaceFlywheelSysId" 1 "StateSpaceFlywheel" 1 "SmartDashboard" 1 "Romi" 1 "RamseteController" 1 "RamseteCommand" 1 "Ramsete" 1 "Preferences" 1 "Pneumatics" 1 "Model" 1 "MecanumControllerCommand" 1 "I2C" 1 "Hardware" 1 "Gyro" 1 "FRC Characterization" 1 "EventLoop" 1 "DriveDistance" 1 "Dashboards" 1 "Characterization" 1 "CAN" 1 "ArmBotOffboard" 1 "ArmBot" 1 "Advanced Java"

Many of these aren't very helpful.

We should come up with a more comprehensive set of tags, and apply them. Some ideas (more are welcome):

Starlight220 commented 1 year ago

Now with the new tag system in place, it's easier to see the following distributions and statistics in the examples: (A full list here, I'm bringing some specific info to attention here.)

We have 62 example projects. (C++ has 63, counting the C one). That's a lot, especially given how repetitive a lot of them are.

Broad categories

Here, the distribution is rather sensible. 24 "basic robot"s are a bit much, but at a third of all examples it's not as bad. We might want some more Romi examples?

Mechanisms

23 differential drives is way too much, especially since most of them have the DifferentialDrive object and not much else. The correlation with the amount of "basic robot"s is obvious. Given the rising popularity of swerve, I'd say we should have more swerve examples, though without vendor code it's a challenge.

Telemetry

For the dashboard that most people use, the Shuffleboard API is majorly underrepresented. We also have absolutely zero examples of the dashboard-agnostic Sendable API.

HID

Shouldn't be too difficult to replace some of the XboxController usages with PS4Controller.


Any ideas? Comments?

auscompgeek commented 1 year ago

Shouldn't be too difficult to replace some of the XboxController usages with PS4Controller.

IMO keeping the XboxController usages is fine. The vast majority of teams are more likely to have an XInput-compatible gamepad over a DualShock 4, since the Logitech F310 is in the rookie KoP.

Starlight220 commented 1 year ago

Are the mappings on the F310 identical to Xbox? If not, the benefit the Xbox class brings to those teams is limited; maybe there's reason to add a class for the F310.

auscompgeek commented 1 year ago

In XInput mode the button mapping on the F310 is identical to an Xbox 360 controller.