diff --git a/scripts/log.py b/scripts/log.py
index 9e856ce2aa84bae2137c5c5be27aa6429e596894..b3511775ba057cbe89c956ac9471b6cabc7c58b2 100644
--- a/scripts/log.py
+++ b/scripts/log.py
@@ -3,21 +3,14 @@ import os
 import datetime
 
 class Log():
-	def __init__(self, filename, **argv):
+	def __init__(self, filename):
 		self.filename = filename
-		self.variables = self.add_variables(**argv)
 
-	def add_variables(self, **argv):
-		with open(self.filename, 'a') as f:
-			for arg in argv:
-				f.write(arg+"\t")
-			f.write("\n")
-		f.close()
 
-	def add_row_entry(self, **argv):
+	def add_row_entry(self, log):
 		with open(self.filename, 'a') as f:
-			for arg in argv:
-				f.write(argv.get(arg)+"\t")
+			for key, value in log.items():
+				f.write(str(value)+"\t")
 			f.write("\n")
 		f.close()
 
diff --git a/scripts/main.py b/scripts/main.py
index 3468b2e192dfc2ef53832ad87ac27f9a15509d3d..8154274a4ff737995ffa6f5b284a353e96f1c926 100755
--- a/scripts/main.py
+++ b/scripts/main.py
@@ -3,11 +3,12 @@
 This is the main class for running the entire game framework
 '''
 #import modules and classes
-
+from log import Log
 #import from libraries
 import enum
 import random
 import time
+import os
 
 #import from ros
 import rospy
@@ -19,34 +20,48 @@ user_placed = (0, 0)
 
 
 class Game(object):
-	def __init__(self):
+	def __init__(self, task_length, n_max_attempt_per_token, timeout):
 		rospy.init_node('big_hero', anonymous=True)
 		# subscriber for getting info from the board
 		rospy.Subscriber("/detected_move", TokenMsg, self.get_move_event_callback)
 		rospy.Subscriber("/board_status", BoardMsg, self.get_board_event_callback)
-		# get the objective of the exercise
+		#get the objective of the exercise from the launch file
+		self.objective = rospy.get_param("/objective")
+
+		#we need a sleep in order to give the system the time to get the board info
 		self.current_board = []
 		rospy.sleep(2)
 		self.initial_board = self.get_board_event()
-		self.objective = rospy.get_param("/objective")
-		self.solution = self.set_objective(5)
+		self.task_length = task_length
+		self.n_max_attempt_per_token = n_max_attempt_per_token
+		self.solution = self.set_objective(self.task_length)
+		self.timeout = timeout
+		self.robot_assistance = 0
+		self.avg_robot_assistance_per_move = 0
+		#counters
 		self.n_attempt_per_token = 1
-		self.n_max_attempt_per_token = 5#n_max_attempt
 		self.n_mistakes = 0
-		self.n_solution = 10#n_solution
 		self.n_correct_move = 0
+		#subscriber variables from detect_move
 		self.detected_token = []
 		self.picked = False
 		self.placed = False
 		self.moved_back = False
-		self.react_time_per_token_t0 = 0
-		self.react_time_per_token_t1 = 0.0
-		self.elapsed_time_per_token_t0 = 0.0
-		self.elapsed_time_per_token_t1 = 0.0
-		self.total_elapsed_time = 0
-		self.move_info = {'token_id':'', 'from':'', 'to':'', 'robot_assistance':'', 'react_time':'', 'elapsed_time':''}
-		self.move_info_vect = list()
-		#log info
+		#logger
+		self.react_time_per_token_spec_t0 = 0.0
+		self.react_time_per_token_gen_t0 = 0.0
+		self.react_time_per_token_spec_t1 = 0.0
+		self.react_time_per_token_gen_t1 = 0.0
+		self.elapsed_time_per_token_gen_t0 = 0.0
+		self.elapsed_time_per_token_spec_t0 = 0.0
+		self.elapsed_time_per_token_gen_t1 = 0.0
+		self.elapsed_time_per_token_spec_t1 = 0.0
+		self.total_elapsed_time = 0.0
+		self.move_info_gen = {'token_id':'', 'from':'', 'to':'', 'avg_robot_assistance_per_move':'', 'cum_react_time':'', 'cum_elapsed_time':'', 'attempt':''}
+		self.move_info_spec = {'token_id': '', 'from': '', 'to': '', 'robot_assistance': '', 'react_time': '',
+		                      'elapsed_time': '', 'attempt': ''}
+		self.move_info_gen_vect = list()
+		self.move_info_spec_vect = list()
 
 	def get_board_event_callback(self, msg):
 		'''callback from the topic board_status to get the status of the current_board'''
@@ -117,9 +132,20 @@ class Game(object):
 
 class StateMachine(enum.Enum):
 
-	#def __init__(self, e):
-
-	#initialise the node and the subscriber
+	def __init__(self, e):
+		self.b_robot_assist_finished = False
+		self.b_robot_feedback_finished = False
+		self.b_user_picked_token = False
+		self.b_user_placed_token_back = False
+		self.b_user_placed_token_sol = False
+		self.b_robot_outcome_finised = False
+		self.b_robot_moved_token_back = False
+		self.b_user_moved_token_back = False
+		self.b_robot_moved_correct_token = False
+		self.b_user_reached_max_attempt = False
+		self.b_user_reached_timeout = False
+		self.b_robot_reengaged_user = False
+	'''States of the State machine'''
 	S_ROBOT_ASSIST = 1
 	S_USER_ACTION = 2
 	S_USER_PICK_TOKEN = 3
@@ -131,30 +157,26 @@ class StateMachine(enum.Enum):
 	S_ROBOT_MOVE_TOKEN_BACK = 9
 	S_ROBOT_MOVE_CORRECT_TOKEN = 10
 	S_ROBOT_OUTCOME = 11
+	S_USER_TIMEOUT = 12
 
 	CURRENT_STATE = 1
 
-	b_robot_assist_finished = False
-	b_robot_feedback_finished = False
-	b_user_picked_token = False
-	b_user_placed_token_back = False
-	b_user_placed_token_sol = False
-	b_robot_outcome_finised = False
-	b_robot_moved_token_back = False
-	b_user_moved_token_back = False
-	b_robot_moved_correct_token = False
-	b_user_reached_max_attempt = False
+
 
 	def robot_provide_assistance(self, game):
 		'''
 		Robot action of assistance combining speech and gesture
 		:return: True when the action has been completed
 		'''
-		print("R_ASSISTANCE")
-		game.move_info['robot_assistance'] = random.randint(0,4)
-		rospy.sleep(2.0)
-		self.b_robot_assist_finished = True
-		self.CURRENT_STATE = self.S_USER_ACTION
+		if self.b_user_reached_timeout==True:
+			print("R_REENGAGE")
+			self.robot_reengage_user()
+		else:
+			print("R_ASSISTANCE")
+			game.robot_assistance = random.randint(0,4)
+			rospy.sleep(2.0)
+			self.b_robot_assist_finished = True
+			self.CURRENT_STATE = self.S_USER_ACTION
 		return  self.b_robot_assist_finished
 
 	def robot_provide_feedback(self):
@@ -167,6 +189,12 @@ class StateMachine(enum.Enum):
 		self.CURRENT_STATE = self.S_USER_PLACE
 		return self.b_robot_feedback_finished
 
+	def robot_reengage_user(self):
+		'''As the timeout occurred the robot reengages the user'''
+		print("RE_ENGAGE USER")
+		self.CURRENT_STATE = self.S_USER_ACTION
+		self.b_robot_reengaged_user = True
+
 	def robot_provide_outcome(self, game):
 		'''
 		Robot provides the user with the outcome of their move
@@ -193,6 +221,7 @@ class StateMachine(enum.Enum):
 			game.set_attempt_per_token(game.n_attempt_per_token)
 			game.set_n_mistakes(game.n_mistakes)
 			self.CURRENT_STATE = self.S_ROBOT_ASSIST
+
 			# check if the user reached his max number of attempts
 			if game.n_attempt_per_token >= game.n_max_attempt:
 				self.S_ROBOT_MOVE_CORRECT_TOKEN = True
@@ -209,6 +238,7 @@ class StateMachine(enum.Enum):
 			game.set_n_mistakes(game.n_mistakes)
 			self.CURRENT_STATE = self.S_ROBOT_MOVE_TOKEN_BACK
 			self.user_move_back(game)
+
 			#check if the user reached his max number of attempts
 			if game.n_attempt_per_token>=game.n_max_attempt_per_token:
 				self.S_ROBOT_MOVE_CORRECT_TOKEN = True
@@ -249,23 +279,51 @@ class StateMachine(enum.Enum):
 		return self.b_user_moved_token_back
 
 	def user_action(self, game):
-		''' Dispach user action'''
-		'''We wait until the user pick a token'''
+		'''user action state has been divided in three sub methods:
+		 1. user pick a token
+		 2. robot provides feedback
+		 3. user place a token
+		  '''
 		print("U_ACTION")
+
+		def check_move_timeout(game):
+			'''we need to check if the computed time (react+elapsed) is smaller than timeout
+			if not, we need to trigger different actions:
+			1. if the user has not picked a token (re-engage)
+			2. if the user has picked a token, ask her to move it back
+			'''
+			current_time = time.time()
+			elapsed_time = current_time-game.react_time_per_token_spec_t0
+			if elapsed_time<game.timeout:
+				return True
+			else:
+				return False
+
+		def placed_back_token(sm):
+			'''As timeout occuccedd when the user has the token in his hand, we
+			 ask him to move it back'''
+			pass
+
+
 		def user_pick_token(sm, game):
-			game.react_time_per_token_t0 = time.time()
+			game.react_time_per_token_spec_t0 = time.time()
 			print("U_PICK")
 			sm.CURRENT_STATE = sm.S_ROBOT_FEEDBACK
 			detected_token, picked, _, _ = game.get_move_event()
 			while(not picked):
-				detected_token, picked, _, _ = game.get_move_event()
-			game.elapsed_time_per_token_t0 = time.time()
-			game.react_time_per_token_t1 = time.time()-game.react_time_per_token_t0
-			game.move_info['react_time'] = game.react_time_per_token_t1
-			game.move_info['token_id'], game.move_info['from'] = game.detected_token[0], game.detected_token[1]
-			sm.user_picked_token = True
-			user_picked = detected_token
-			return sm.user_picked_token
+				if check_move_timeout(game):
+					detected_token, picked, _, _ = game.get_move_event()
+				else:
+					sm.b_user_reached_timeout = True
+					game.react_time_per_token_spec_t0 = time.time()
+					return False
+
+			game.elapsed_time_per_token_spec_t0 = time.time()
+			game.react_time_per_token_spec_t1 = time.time()-game.react_time_per_token_spec_t0
+			game.react_time_per_token_gen_t1 += game.react_time_per_token_spec_t1
+			sm.b_user_picked_token = True
+			return sm.b_user_picked_token
+
 		def robot_provide_feedback(sm):
 			print("R_FEEDBACK")
 			sm.CURRENT_STATE = sm.S_USER_PLACE
@@ -274,28 +332,30 @@ class StateMachine(enum.Enum):
 		''' When the user picked the token we check where they place it'''
 		'''either they can place it back '''
 		def user_place(sm, game):
+			'''user place has been divided into:
+			   1. user places a token back
+			   2. user places a token in a solution row
+			'''
 			print("U_PLACE")
 			#check where the user will place the token
 			def user_place_token_back(sm):
 				print("U_PLACE_BACK")
 				sm.CURRENT_STATE = sm.S_USER_ACTION
 				sm.b_user_placed_token_back = True
-				game.elapsed_time_per_token_t1 = time.time()-game.elapsed_time_per_token_t0
-				game.move_info['to'] = game.detected_token[2]
-				game.move_info['elapsed_time'] = game.elapsed_time_per_token_t1
+				game.elapsed_time_per_token_spec_t1 = time.time()-game.elapsed_time_per_token_spec_t0
+				game.elapsed_time_per_token_gen_t1 += game.elapsed_time_per_token_spec_t1
 				return sm.b_user_placed_token_back
 			'''or they can place it in the solution row'''
 			def user_place_token_sol(sm):
 				print("U_PLACE_SOL")
 				sm.CURRENT_STATE = sm.S_ROBOT_OUTCOME
 				sm.b_user_placed_token_sol = True
-				game.elapsed_time_per_token_t1 = time.time() - game.elapsed_time_per_token_t0
-				game.move_info['to'] = game.detected_token[2]
-				game.move_info['elapsed_time'] = game.elapsed_time_per_token_t1
+				game.elapsed_time_per_token_spec_t1 = time.time() - game.elapsed_time_per_token_spec_t0
+				game.elapsed_time_per_token_gen_t1 += game.elapsed_time_per_token_spec_t1
 				return sm.b_user_placed_token_sol
 			'''return where the user placed the token'''
-			#here we get the token that has been placed and trigger one or the other action
 
+			#here we check whether a token has been picked, and where it has been placed
 			detected_token, picked, placed, moved_back = game.get_move_event()
 			while (not placed):
 				detected_token, _, placed, moved_back = game.get_move_event()
@@ -316,17 +376,18 @@ class StateMachine(enum.Enum):
 			else:
 				self.CURRENT_STATE = self.S_USER_PICK_TOKEN
 		else:
-			self.CURRENT_STATE = self.S_USER_ACTION
+			self.CURRENT_STATE = self.S_ROBOT_ASSIST
 
 	def num_to_func_to_str(self, argument):
 		switcher = {
 		        0: self.robot_provide_assistance,
-		        1: self.robot_provide_feedback,
-		        2: self.user_action,
-			    3: self.robot_provide_outcome,
-				4: self.robot_move_back,
-				5: self.user_move_back,
-				6: self.robot_move_correct_token
+				1: self.robot_reengage_user,
+		        2: self.robot_provide_feedback,
+		        3: self.user_action,
+			    4: self.robot_provide_outcome,
+				5: self.robot_move_back,
+				6: self.user_move_back,
+				7: self.robot_move_correct_token
 		    }
 
 		# get the function based on argument
@@ -339,35 +400,93 @@ class StateMachine(enum.Enum):
 
 
 def main():
+	game = Game(task_length=5, n_max_attempt_per_token=4, timeout=15)
+	input = raw_input("please, insert the id of the user")
+	path_name = os.getcwd() + "/log/" + input
+	if not os.path.exists(path_name):
+		os.makedirs(path_name)
+	else:
+		input = raw_input("The folder already exists, please remove it or create a new one")
+		path_name = os.getcwd() + "/log/" + input
+		if not os.path.exists(path_name):
+			os.makedirs(path_name)
+
+	file_spec = path_name + "/log_spec.txt"
+
+	file_gen = path_name + "/log_gen.txt"
+
+	log_spec = Log(file_spec)
+	game.move_info_spec['token_id'] = "token_id"
+	game.move_info_spec['from'] = "from"
+	game.move_info_spec['to'] = "to"
+	game.move_info_spec['robot_assistance'] = "robot_assistance"
+	game.move_info_spec['react_time'] = "react_time"
+	game.move_info_spec['elapsed_time'] = "elapsed_time"
+	game.move_info_spec['attempt'] = "attempt"
+	game.move_info_spec_vect.append(game.move_info_spec)
+	log_spec.add_row_entry(game.move_info_spec)
+
+	log_gen = Log(file_gen)
+	game.move_info_gen['token_id'] = "token_id"
+	game.move_info_gen['from'] = "from"
+	game.move_info_gen['to'] = "to"
+	game.move_info_gen['avg_robot_assistance_per_move'] = "avg_assistance_per_move"
+	game.move_info_gen['cum_react_time'] = "cum_react_time"
+	game.move_info_gen['cum_elapsed_time'] = "cum_elapsed_time"
+	game.move_info_gen['attempt'] = "attempt"
+	game.move_info_gen_vect.append(game.move_info_gen)
+	log_gen.add_row_entry(game.move_info_gen)
 
-
-	game = Game()
-	game.set_n_solution(5)
-	game.set_n_max_attempt_per_token(4)
-	current_board = game.get_board_event()
-	#game.solution = game.set_objective(n_solution)
 	sm = StateMachine(1)
 
-	while game.get_n_correct_move()<game.n_solution:
+	while game.get_n_correct_move()<game.task_length:
 		if sm.CURRENT_STATE.value == sm.S_ROBOT_ASSIST.value:
 			sm.robot_provide_assistance(game)
+			game.avg_robot_assistance_per_move += game.robot_assistance
 		elif sm.CURRENT_STATE.value == sm.S_USER_ACTION.value:
 			time_to_act = time.time()
 			sm.user_action(game)
-			game.total_elapsed_time += time.time()-time_to_act
+			if  game.detected_token:
+				game.move_info_spec['token_id'] = game.detected_token[0]
+				game.move_info_spec['from'] = game.detected_token[1]
+				game.move_info_spec['to'] = game.detected_token[2]
+				game.move_info_spec['robot_assistance'] = game.robot_assistance
+				game.move_info_spec['react_time'] = round(game.react_time_per_token_spec_t1, 2)
+				game.move_info_spec['elapsed_time'] = round(game.elapsed_time_per_token_spec_t1)
+				game.move_info_spec['attempt'] = game.n_attempt_per_token
+				game.total_elapsed_time += time.time()-time_to_act
+				game.move_info_spec_vect.append(game.move_info_spec)
+				log_spec.add_row_entry(game.move_info_spec)
+
 		elif sm.CURRENT_STATE.value == sm.S_ROBOT_OUTCOME.value:
 			sm.robot_provide_outcome(game)
-
-			print("game_state:", game.get_n_correct_move(), "n_attempt_token:", game.get_n_attempt_per_token())
-			print("react time: ", game.react_time_per_token_t1, "elapsed time: ", game.elapsed_time_per_token_t1)
-			game.move_info_vect.append(game.move_info.copy())
-			print(game.move_info)
-
-	print("correct_move ", game.get_n_correct_move,
-	      " n_mistakes ", game.n_mistakes)
-	for instance in game.move_info_vect:
-		print(instance)
-
+			#{'token_id':'', 'from':'', 'to':'', 'robot_assistance':'', 'react_time':'', 'elapsed_time':'', 'attempt':''}
+			game.move_info_gen['token_id'] = game.detected_token[0]
+			game.move_info_gen['from'] = game.detected_token[1]
+			game.move_info_gen['to'] = game.detected_token[2]
+			game.move_info_gen['avg_robot_assistance_per_move'] = game.avg_robot_assistance_per_move/game.n_attempt_per_token
+			game.move_info_gen['cum_react_time'] = game.react_time_per_token_gen_t1
+			game.move_info_gen['cum_elapsed_time'] = game.elapsed_time_per_token_gen_t1
+			game.move_info_gen['attempt'] = game.n_attempt_per_token
+			game.move_info_gen_vect.append(game.move_info_gen)
+			log_gen.add_row_entry(game.move_info_gen)
+			game.react_time_per_token_spec_t1 = 0
+			game.react_time_per_token_gen_t1 = 0
+			game.react_time_per_token_spec_t0 = 0
+			game.react_time_per_token_gen_t0 = 0
+			game.elapsed_time_per_token_spec_t1 = 0
+			game.elapsed_time_per_token_gen_t1 = 0
+			game.elapsed_time_per_token_spec_t0 = 0
+			game.elapsed_time_per_token_gen_t0 = 0
+			game.avg_robot_assistance_per_move = 0
+
+	for instance_spec in game.move_info_spec_vect:
+		print(instance_spec)
+
+	for instance_gen in game.move_info_gen_vect:
+		print(instance_gen)
+
+	print(game.total_elapsed_time)
 
 
 if __name__ == '__main__':