There is talk in the commentary regarding having code to detect if there is a restart by examining the logs.
Can anyone clarify what state the logs are in before the race/at the start of racing?
- Does the logs folder itself exist, but empty of all files?
- There is not even a logs folder, it is created when the first log is created?
Any advice would be appreciated
Thanks
- Pi Hard

The log folder doesn't exist to start with unless you've included it as part of your upload. Its created early on in the Race.py file when it calls
and
from the RaceCodeFunctions.py file.
The way Claire suggests on the stream is during boot up to check for the existance of either
Processing %s.txtorUser %s.txtwhere %s is the local time. It's a pretty good solution, but it could have problems if your robot has to be rebooted or if your check happens after the logs files have been created.I've taken a slightly different approach. At the start of the race, when the light turns second green I quickly write an empty file to the log folder. Then, during the startup (or restart) I check for the existence of that file. If it finds that file, it's because we restarted during the session and it goes straight back to racing. If it doesn't find the file, it continues to wait for the light sequence.
Like Jamie, I decided to create another file. I write a timestamp in it to check that it isn't from an earlier race or testing simulation and to have it stop on time for Arron. The code I use follows:
###################################################### ### Race.py ###################################################### StartDetailedLoging() StartUserLog() CheckStartedRace() Speed(100) #Set Race Speed if Globals.raceEndTime == 0.0: #variable is set to 0.0 by default in Globals.py endTime = float(time.time()) + (10.0 * 60.0) #race just started else: endTime = Globals.raceEndTime #varibale is different because race has started while time.time() < endTime: #Your race code goes here ###################################################### ### Globals.py ###################################################### raceEndTime = 0.0 ###################################################### ### RaceCode Functions.py ###################################################### def CheckStartedRace(): #Check to see if the race has started and decide to go or wait. if True: #try: logPath = './logs/MyRaceStarted.txt' #set file path if not os.path.isdir('./logs'): #check if directory exists os.mkdir('./logs') #make directory if os.path.isfile(logPath): #check if file exists logFile = open(logPath, 'r') #open file as read only logLine = logFile.read() #get start time logFile.close() #close file if time.time() < (float(logLine) + (10 * 60)): #check if race is still going print '################### GO!!! - time.time() is less than endTime' # Debugging Globals.raceEndTime = (float(logLine) + (10 * 60)) # Set user created variable for while loop in race.py ImageProcessor.SetImageMode(3) # GO Straight return print '################## CheckStartedRace(): Race NOT started.' WaitForGo() #race hasn't started yet RaceStartedLog() #create race started log file def RaceStartedLog(): logPath = './logs/MyRaceStarted.txt' #set file path logFile = open(logPath, 'w') #open/create file as write only logLine = '%s' % (time.time()) #get time stamp logFile.write(logLine) #write time stamp to file logFile.close() #close file###################################################### ### Race.py ###################################################### import time import Globals StartUserLog() CheckStartedRace() if Globals.raceEndTime == 0.0: #variable is set to 0.0 by default in Globals.py endTime = float(time.time()) + (Globals.raceDuration * 60.0) #(Minutes * Seconds) else: endTime = Globals.raceEndTime #varibale is different because race has started while time.time() < endTime: #Your race code goes here ###################################################### ### Globals.py ###################################################### ### RESTART ### raceEndTime = 0.0 raceDuration = 1.0 #!!! EXPERIMENTING !!! #raceDuration = 2.0 #!!! TESTING Round !!! #raceDuration = 3.0 #!!! CHALLENGE Round !!! #raceDuration = 10.0 #!!! RACE Round !!! ###################################################### ### RaceCode Functions.py ###################################################### import time import inspect import os def CheckStartedRace(): #Check to see if the race has started and decide to go or wait. if True: #try: logPath = './logs/MyRaceStarted.txt' #set file path if not os.path.isdir('./logs'): #check if directory exists os.mkdir('./logs') #make directory if os.path.isfile(logPath): #check if file exists logFile = open(logPath, 'r') #open file as read only logLine = logFile.read() #get start time logFile.close() #close file if time.time() < (float(logLine) + (Globals.raceDuration * 60.0)): #check if race is still going print '################### GO!!! - time.time() is less than endTime' # Debugging Globals.raceEndTime = (float(logLine) + (Globals.raceDuration * 60.0)) # Set user created variable for while loop in race.py ImageProcessor.SetImageMode(3) # GO Straight return print '################## CheckStartedRace(): Race NOT started.' WaitForGo() #race hasn't started yet RaceStartedLog() #create race started log file def RaceStartedLog(): logPath = './logs/MyRaceStarted.txt' #set file path logFile = open(logPath, 'w') #open/create file as write only logLine = '%s' % (time.time()) #get time stamp logFile.write(logLine) #write time stamp to file logFile.close() #close fileWeird Duplicate
I'm only here because I wanted to try to get comment #666. :(
I have an idea for a very simple boot-detection method very similar/identical to what Jamie has described above. We may have even used it for the first time in a race last night. Should be universal but I will have a look at how it would fit into the standard code tonight and drop a few lines of code here as an example.
Beware of making assumptions about what might be in the formulapi folder. For example I see the entire set of standard code modules in that folder even though they are not part of my uploads. (In fact I now rely on the ThunderBorg.py module being in that folder, even though I don't upload it.) After the first suggestion of reboot detection methods last season it turned out that the logs folder wasn't actually being emptied as had been stated and that caused a false start for one competitor (RasPerras?). I believe since then it is now routinely emptied or deleted but I'm not 100% sure. Hope Arron can confirm.
We empty the
~/formulapi/logsfolder each time we write the card, just before we copy over the uploaded code into~/formulapiThis means that the
~/formulapi/logsfolder should exist when your code is started and will be empty unless your uploaded code includes alogsfolder with data in it already. The standard upload script excludes everything in thelogsfolder to be safe :)Pico is right that we had a problem in the past which has now been fixed. Put simply if you run
it will work, unless there are a large number of files. When it fails it leaves them all in place :(
We solved this by changing the script to
which will work regardless of how many files are saved.
The standard image we write the uploaded code to already includes a full copy of the Formula Pi code, meaning teams could just upload the files they have changed. We would advise you to upload all files anyway as that copy is a bit out of date now. It will always have a working copy of
ThunderBorg.pythough :)Thanks everyone for your help and suuggetsions.
We've now put some code in to hopefully restart on a powercycle.
We've also updated race.py to try and drive into as many walls as possible to hopefully trigger a powercycle. This should look pretty odd as we zigzag across the track.
Bring on the next round, and the consequent mayhem.
Having spent my fair share of time running into the walls I found that it doesn't normally force a restart. Most of the restarts have been during racing and crashing into other mosterborgs. If you want to test a reboot, you could just manually reboot with this code.
import os os.system('sudo shutdown -r now') # the -r is the part that reboots - it's important not to forget itYou could trigger it every time you cross the line, or just once at a particular point on the track. It would be more reliable, and you don't have to purposely run the monsterborg into the walls.
Add new comment