- Python Tutorial 1
- Contributing using GitHub
Python Tutorial 1
Robotics while loop
The while loop is a convenient way to do the same task over and over again. This comes up a lot in robotics, where it is often desirable to let something run in a tight loop forever. A good example of this is code which interfaces with an instrument. In this case, it is common to write code that simply spends all of its time checking the instrument for updates, and then publishing that information.
A simple example of this behavior is demonstrated below using the system clock. Out of the box, computers are all very good at keeping time, and this code shows how to publish that information at a constant rate.
1 2 3 4 5 6 7 8 import time starttime = time.time() while True: currenttime = time.time() print("Time is %.02f seconds"%currenttime) time.sleep(0.1)
This code is an example of an infinite loop. It will run forever doing something of questionable importance. To stop the loop, either close the terminal running python or push CTLR + c.
The time printed to the screen is in seconds since January 1st, 1970. This is known as Unix epoch time.
There are several things going on in this code, and since this is a tutorial they will be broken down line by line.
The first line is an import statement. Quoting from the first line of the python documentation, “Python code in one module gains access to the code in another module by the process of importing it.” This is a fairly precise definition, but in essence this allows code to use the requested module. time is a built in python module, and if python is running this import will work. This is not always the case, and sometimes getting imports to work is a real challenge :)
The time module has within it a number of functions that relate to computer time. The relevant functions are time and sleep. Though a bit weird perhaps, it is not uncommon in python for a word to be repeated twice with a period in between, as in line 3.
The while loop begins on line 5. A particular characteristic of python appears in this statement. Code blocks which can extend for an arbitrary number of lines are first ended with the colon character. The code associated with this code block (in this case a while loop) is then indicated by indentation. All statements below the while loop moved one or more tab spaces in from the while loop are a part of the while loop.
The print function is how the information moves from inside the program to the computer screen. This is a relatively complicated issue in general for robotics, where information is moved between many programs frequently. In this example the simplest method is used, simply printing the information to the terminal. More complicated information transfer is a topic for a later tutorial, but the print function is a frequently used first step to understanding a new output.
The print line uses sting formatting to insert a variable into the printed statement. It is possible to simply print the variable by itself as
This is often simpler to code, but the output is harder to read. Reviewing the documentation the % character is discouraged, but force of habit is hard to break.
The last line of the while loop is a sleep statement. This is used to free up the CPU for 1/10 of a second, a long time to a computer. Like the print statement, the sleep statement is a simple approach to a complicated topic, in this case process management. This method will be extensively used in the robot and covered further in future tutorials. This design decision is essentially equivalent to the statement Nothing needs to be addressed within 1/10 of a second.
The second example in this tutorial is a slight extension of the first. The template for a mission task has a few distinctions from the instrument reading loop show above. In general, these tasks are designed to complete, and good practice further ensures that all mission tasks terminate by adding a timeout condition.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import time isrun = True starttime = time.time() while isrun: currenttime = time.time() # mission completion check if False: isrun = False # timeout condition if (currenttime - starttime) > 3: break print("Time is %.02f seconds"%currenttime) time.sleep(0.1) print("Goodbye World")
The while loop in this example checks a variable before it begins execution. If isrun is False, the while loop exits before execution. As written, the while loop will never terminate in this way, but it might be fun to try and change this behavior.
The timeout behavior takes place on line 14, which checks the current time and exits if it has been more than 3 seconds from the start of the loop. The loop is then immediately terminated with the break statement. The if loop, and the break statement are examples of flow control.
The last action of this code is to print the line “Goodbye World”. This shows how to write code both inside and outside of the while loop.
Well, that is it for now. Hopefully the basic topics covered here will continue to be useful into the future.
Contributing using GitHub
In order to contribute to Zoidberg code it is first necessary to get a Github account. This is simple to do at Github. This tutorial covers version control using the program git, which is a command line tool. There are other tools to to do the same thing which use a GUI, but they may use other workflows which could mess up the repository.
Fork and Pull workflow
To get a better understanding of Git and the process we’ll be using, check out these guides on the Fork and Pull workflow.
- general GitHub guides
- a good rundown on the Fork and Pull workflow. This is the source of much of the information on this page.
- Git stash
The key points are used from these guides. In all cases the web page repository is used as an example, though this should work for any code repository with minor changes in names. Additionally, the dummy account newuser is used as a place holder. After you get your own github account, use your own account name in place of newuser.
Fork the repository
Do not work directly on the main code repository. This is any code owned by the username sdcityrobotics, i.e. https://github.com/sdcityrobotics/sdcityrobotics.github.io
To edit code on the main repository, first fork the repo onto your own github account. Navigate to the code repository page that you are interested in. (Same link as above). Fork the repo (click the Fork button on the web page).
After forking, there is a new repository in your github account. It is now possible to navigate to this new repository. i.e. https://github.com/newuser/sdcityrobotics.github.io
Clone your Fork onto your local computer, somewhere you can work on it. Where this is is a matter of choice, the user home folder is used in this example. The URL used in this example is found on your new repository web page. This is found by clicking on the clone or download button on this web page. The SSH version of this url is used in this example instead of the default HTTPS link, because it is simple to set up security keys and then no longer need to log in each time to commit code.
cd ~ git clone firstname.lastname@example.org:newuser/sdcityrobotics.github.io.git
This will create a new folder, sdcityrobotics.github.io, in the home folder. navigate into the new folder before doing anything else!
- Add the main repository as the upstream repository
# Add 'upstream' repo to list of remotes git remote add upstream email@example.com:sdcityrobotics/sdcityrobotics.github.io.git # Verify the new remote named 'upstream' git remote -v
Keeping your fork up to date
Before doing anything with your fork, it is important to make sure that it is up-to date. This is done by fetching from the upstream repository
# Fetch from upstream remote git checkout master git fetch upstream git rebase upstream/master # push these changes to you local repository git push origin # View all branches, including those from upstream git branch -va
Create a branch
From Chaser324 guide:
Whenever you begin work on a new feature or bug fix, it’s important that you create a new branch. Not only is it proper git workflow, but it also keeps your changes organized and separated from the master branch so that you can easily submit and manage multiple pull requests for every task you complete.
- Check out a branch:
git checkout -b BRANCH_NAME upstream/master git push --set-upstream origin BRANCH_NAME
It is really important to remember to work on the latest code, see :ref:
You are free to hack away. It is nice if you can keep the things you work on to a minimum for each branch, i.e fix one problem on one branch, and add a new feature on another. Once you have begun to work on things it is harder to keep up with others work, and so this leads to the need for git stash.
- commit and push your changes:
# This shows you a list of all the changes made. If a new file is added, or if # the name of a file has been changed, it is necessary to use the git add # command git status git commit -am "COMMENT OF WHAT YOU DID" git push origin
- Once you have pushed to your Fork, you’ll go to GitHub and do a Pull Request so that your code can be reviewed and then merged into the main project