Restart code

9 posts / 0 new
Last post
jonnus
jonnus's picture
Restart code

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?

  1. Does the logs folder itself exist, but empty of all files?
  2. There is not even a logs folder, it is created when the first log is created?

Any advice would be appreciated

Thanks

- Pi Hard

Jamie
Jamie's picture
Restarting

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

StartDetailedLoging() 

and

StartUserLog()

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.txt or User %s.txt where %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.

jtobinart
jtobinart's picture
Re: Restart

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
jtobinart
jtobinart's picture
Updated version:

######################################################
### 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 file
jtobinart
jtobinart's picture
Weird Duplicate

Weird Duplicate

picos_pit_crew
Comment #667

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.

Arron Churchill
Arron Churchill's picture
Logs folder

We empty the ~/formulapi/logs folder each time we write the card, just before we copy over the uploaded code into ~/formulapi

This means that the ~/formulapi/logs folder should exist when your code is started and will be empty unless your uploaded code includes a logs folder with data in it already. The standard upload script excludes everything in the logs folder to be safe :)

Pico is right that we had a problem in the past which has now been fixed. Put simply if you run

sudo rm -r /home/pi/formulapi/logs/*

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

sudo rm -r /home/pi/formulapi/logs
mkidr /home/pi/formulapi/logs

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.py though :)

jonnus
jonnus's picture
Thanks

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.

Jamie
Jamie's picture
Walls

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 it

You 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

Filtered HTML

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd> <pre>
  • Syntax highlight code surrounded by the <pre class="brush: lang">...</pre> tags, where lang is one of the following language brushes: bash, cpp, perl, python.
  • Lines and paragraphs break automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Comment Images
Files must be less than 10 MB.
Allowed file types: png gif jpg jpeg.
Comment Attachments
Files must be less than 10 MB.
Allowed file types: txt pdf nfo doc docx rtf jpg png gif bmp zip tar gz csv xls.
CAPTCHA
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.