{"id":20536436,"url":"https://github.com/stuypulse/motorlab","last_synced_at":"2025-04-09T21:18:18.102Z","repository":{"id":134381813,"uuid":"562544035","full_name":"StuyPulse/MotorLab","owner":"StuyPulse","description":null,"archived":false,"fork":false,"pushed_at":"2024-12-13T22:46:58.000Z","size":887,"stargazers_count":0,"open_issues_count":0,"forks_count":73,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-09T21:18:12.874Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/StuyPulse.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-11-06T17:20:15.000Z","updated_at":"2022-11-06T17:20:21.000Z","dependencies_parsed_at":"2023-12-10T01:43:43.539Z","dependency_job_id":"f6c2a966-a16f-498c-a9f3-7879b01844e3","html_url":"https://github.com/StuyPulse/MotorLab","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":"StuyPulse/Phil","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StuyPulse%2FMotorLab","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StuyPulse%2FMotorLab/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StuyPulse%2FMotorLab/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StuyPulse%2FMotorLab/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/StuyPulse","download_url":"https://codeload.github.com/StuyPulse/MotorLab/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248111973,"owners_count":21049578,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-16T00:36:40.789Z","updated_at":"2025-04-09T21:18:18.081Z","avatar_url":"https://github.com/StuyPulse.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MotorLab\n\u003cdetails\u003e\n\u003csummary\u003e\nInstalling from GitHub\n\u003c/summary\u003e\n\u003cbr\u003e\n\n## Installation\n\n### Github\nMake sure you're signed in on https://github.com/ before you start. To make a fork of this code so that you can edit and keep your own version, click on the \"fork\" button at the top right (shown below). Leave all of the settings as is and press \"fork\" again.\n![Fork button on github](images/fork.png)\n\nTo download your code go back to https://github.com/ and find the new MotorLab that is under YOUR github account. Click on “Code”, then “HTTPS”, and then copy the link.\n![Cloning from github using HTTPS](images/clone.png)\n\nOpen Git Bash (or Terminal if you're on a Mac) and type `git clone \u003clink here\u003e` (in Git Bash you may need to right click and press paste).\n![Cloning in git bash](images/term.png)\n    \n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\nSaving to GitHub\n\u003c/summary\u003e\n\u003cbr\u003e\n    \n### Push to Github\n\nThere are 3 steps to pushing to Github: Adding, Committing, and Pushing.\n\n#### Adding\n\nBefore pushing code to github, you have to choose which changes you want to include. VSCode has a git menu, as shown in the picture below. If you want to add the changes from a certain file, you can hover over the file name and click \"+\". This will bring the changes into the \"Staged Changes\" section.\n\n![Git menu in VSCode](images/stage.jpg)\n\n#### Committing\n\nCommits are a way of grouping changes that you're going to push to github. You can add a message to your commit in the text box above \"Staged Changes\". To commit, click the check mark.\n\n![Commit in VSCode](images/commit.jpg)\n\n#### Pushing\n\nOnce you've committed, all thats left is to sync your local changes with the code online. To do this, press the blue \"Sync Changes\" button or click on the three dots by \"Source Control\" and click \"Push\".\n\n![Push in VSCode](images/push.jpg)\n\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003e\nCoding in VSCode\n\u003c/summary\u003e\n\u003cbr\u003e\n\n### Coding\nOnce you've cloned your code, open the MotorLab folder in VSCode. The only file you'll be editing is [DriveFunctions.java](src/main/java/com/stuypulse/robot/commands/DriveFunctions.java) (`src/main/java/com/stuypulse/robot/commands/DriveFunctions.java`).\n![DriveFunctions.java](images/drivefuncs.png)\nThis is what the file should look like (some lines cut). You'll be coding in each section enclosed by `{}`, and depending on which command you run this code will be run continuously in a loop.\n\nFor example, the code below will run the left motor at 100% forever when the `Drive Forwards` command is run.\n![Code example](images/driveexample.png)\n\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003e\nRunning in VSCode\n\u003c/summary\u003e\n\u003cbr\u003e\n\n### Running your code\nYou can run any of your functions whenever you want to test them in a simulated environment (as long as you aren't on a Mac 😢).\n\nTo run your code, press Ctrl+Shift+P or click on the WPILib logo at the top right.\n\n![Run prompt](images/runprompt.png)\n\nThen select `WPILib: Simulate Robot Code on Desktop`\n\n![Run options](images/runmenu.png)\n\nHit `OK` and the program should start running.\nTo select which command to run, use the Autonomous drop down shown below and choose your command.\n\n![Auto selector](images/autochooser.png)\n\nTo run the robot, click on \"Autonomous\" in the robot state selector. To restart, press \"Disabled\" and then \"Autonomous\" again.\n\n![Robot state selector](images/robotstate.png)\n\n\u003c/details\u003e\n\n## MotorLab\n\nMotors are the cause of movement on a robot, so understanding how to interact with them in code is fundamental for robot programming. \n\nIn general, motors are devices that convert electrical energy into motion, which is a complicated way of saying that they spin when you power them. As a result, the most common way to get a motor to do something is to give it what's called a *duty cycle*, which is a value between -1.0 and +1.0 which dictates at what percent of full power the motor will spin at. \n\nThese facts about motors are reflected in the code that is used to control them. The most common way motors are controlled in code is by setting their *duty cycle*, usually by something that looks like `motor.set(1.0)`. \n\nFor a robot's drivetrain, motors allow it to move, whether that be through human input or autonomous routines. This lab will guide you through a series of challenges about simple drivetrain motion as well as simple autonomous control using **control theory**.\n\n\n### Motor Functions\n\u003ctable\u003e\n    \u003cthead\u003e\n        \u003ctr\u003e\n            \u003cth\u003eFunction\u003c/th\u003e\n            \u003cth\u003eDescription\u003c/th\u003e\n            \u003cth\u003eReturns\u003c/th\u003e\n        \u003c/tr\u003e\n    \u003c/thead\u003e\n    \u003ctbody\u003e\n        \u003ctr\u003e\n            \u003ctd\u003eleft.set(x)\u003c/td\u003e\n            \u003ctd rowspan=2\u003eSet the motor percentage to x, a value from 1.0 to -1.0 (1.0 is full speed forwards, -1.0 is full speed backwards).\u003c/td\u003e\n            \u003ctd rowspan=2\u003enothing (void)\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003ctd\u003eright.set(x)\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003ctd\u003eleft.getDistance()\u003c/td\u003e\n            \u003ctd rowspan=2\u003eReturns the distance in inches the motor has traveled. NOTE: if the robot moves 3 inches forward and 3 backwards, the distance will be 0.\u003c/td\u003e\n            \u003ctd rowspan=2\u003edouble\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003ctd\u003eright.getDistance()\u003c/td\u003e\n        \u003c/tr\u003e\n    \u003c/tbody\u003e\n\u003c/table\u003e\n\n## Challenges:\n\nUsing the **Motor Functions** given above, and all the Java knowledge learned (data types, variables, operators, if's and conditionals), complete these challenges within the brackets for a given function. They can be found in the [DriveFunctions.java](src/main/java/com/stuypulse/robot/commands/DriveFunctions.java) file. \n\nWhat you code will be run continuously, so you do **NOT** need loops to run these functions. That is handled for you.\n\n\u003cdetails\u003e\u003csummary\u003eDriving\u003c/summary\u003e\u003cbr\u003e\nSimply get your romi to drive straight! No need to stop it.\n\nUse `void driveForwards(Motor left, Motor right) {}`.\n\nJust like the last command, but backwards:\n\nUse `void driveBackwards(Motor left, Motor right) {}`.\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003eTurning\u003c/summary\u003e\u003cbr\u003e\nMake your romi turn in-place clockwise (to the right). It should spin around its center.\n\nYou'll need to think about this one!\n\nUse `void turnRight(Motor left, Motor right) {}`.\n\nDo it again but counter-clockwise (to the left):\n\nUse `void turnLeft(Motor left, Motor right) {}`.\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003eBasic Autonomy\u003c/summary\u003e\u003cbr\u003e\nUntil this point, the robot has just run infinitely based on what you have hard coded. Let's get it to move a little smarter by having it drive to a distance.\n\nThis is considered autonomous motion as the robot is moving without human instruction.\n\nThe distance that we want the robot to stop at is called the *setpoint*. Create a variable inside the function that represents the setpoint, and set it to `60.0`. (it can really be anything, but 60 is a good distance). \n\nCreate code that drives forward, but stops once the robot has past its setpoint.\n\nUse `void stopDistance(Motor left, Motor right) {}`.\n\nWhat you have created is a *control law*, which is a mathematical formula or some logic that will make a robot's *measurement* approach a *setpoint*. \n\nIn our case the *measurement* is the distance travelled by the motors, and the *setpoint* is where we want the motors to be. By telling the motors to drive forward when the *setpoint* has not been reached, we are increasing the measurement until it approaches a setpoint.\n\nA good *control law* is essential for autonomous control. \n\u003c/details\u003e\n    \n\u003cdetails\u003e\u003csummary\u003eBang Bang\u003c/summary\u003e\u003cbr\u003e\n\nThere are several issues with our first control law. Firstly, if our robot is really heavy and we let it get to a high speed, by the time we tell it to stop, it will simply roll past the *setpoint*. \n\nA related issue is that the control law does not handle if the robot is in front of its setpoint. If the robot rolls over its setpoint or the setpoint started behind the robot, then it will not tell the robot to not move. \n\nWrite a more advanced control law that can move the robot back to its setpoint, rather than just stopping it. \n\nUse `void bangBang(Motor left, Motor right) {}`.\n\nThis control law is called Bang-Bang.\n\u003c/details\u003e\n    \n\u003cdetails\u003e\u003csummary\u003eLess Bang\u003c/summary\u003e\u003cbr\u003e\nBang Bang will *technically* work, but clearly when you run it, it continually oscillates around the setpoint. It has same issue as our first law, where making sudden changes in direction can be inconsistent and dangerous.\n\nYou can change how fast the Bag Bang law runs by simply running the motors at a smaller value (as opposed to -1.0 and +1.0). When the value is smaller, the robot will reach the setpoint slower but there will be smaller oscillations. When the value is higher, the robot reaches the setpoint quickler, but with larger oscillations.\n\nFor this Bang Bang version, play around with the value you are sending the motors to find a good balance of response time to oscillations. This is a manual process called *tuning*. \n\nUse `void lessBang(Motor left, Motor right) {}`\n\u003c/details\u003e\n    \n\u003cdetails\u003e\u003csummary\u003eProportional Control\u003c/summary\u003e\u003cbr\u003e\n\nWe can get inspiration for another control algorithm from real life.\n\nWhenever you're running across the street to not miss the light, you run full speed across the street. As you approach the curb, though, you don't want to run full speed to the mom with her two kids standing there. So, you slow down as you run to the curb. The effort you put into running is proportional to how far you are from the curb.\n\nWhen we are farthest from the curb, we want to run as fast as possible, but when we are are at the curb we don't want to be moving. In between, we want to slow down.\n\nThis can be put into terms we already know. The *setpoint* is the width of the street (initial distance to the curb). The *measurement* is how far you've already run into the street. \n\nWe want to introduce a new term, *error* which is the *setpoint* minus the *measurement*.\n\nWhen running across the curb, the effort is proportional to error, and when getting a robot to drive to a distance, the *duty cycle* is \nproportional to the error.\n\nCode the control law described above so that when the autonomous routine starts it will calculate `1.0` exactly and will decrease down to `0.0` as the robot drives forward. Once you find this value, scale it up or down as needed to find a good balance between response time and oscillations.\n\n**THERE ARE NO `if` STATEMENTS NECESSARY**\n\nUse `void betterControl(Motor left, Motor right) {}`.\n\nThis control algorithm is called a P-Control, which is one component of a greater algorithm called PID-Control.\n\n\u003c/details\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstuypulse%2Fmotorlab","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstuypulse%2Fmotorlab","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstuypulse%2Fmotorlab/lists"}