Skip to content

Instantly share code, notes, and snippets.

@Banteel
Last active January 18, 2023 21:00
Show Gist options
  • Save Banteel/6bece774e02830576563a69e5ea324b7 to your computer and use it in GitHub Desktop.
Save Banteel/6bece774e02830576563a69e5ea324b7 to your computer and use it in GitHub Desktop.
Non-Asyncio Simple Dock with ChargerMarker: A non-asyncio Simple_Dock with Chargermarker that is Python 3.6 safe for Cozmo robot
#!/usr/bin/env python3
# based on Copyright (c) 2016 Anki, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License in the file LICENSE.txt or at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# simple_dock_with_chargermarker_non_asyncio
# This script can use Walls & a Charger Marker to locate the Charger
# The Walls, FreePlay Lights, & Charger Marker can be turned off & on as needed
# This script does not require any of these options to be turned on, all you need is a Charger
# This script is the Non Asyncio version of the simple_dock_with_ChargerMarker script
#
#
# forked script from: cozmo_unleashed
#
# Original perpetual Cozmo_Unleashed script by AcidZebra
# This Script is made by VictorTagayun and is heavily slimmed down to only docking
# Script based on the Cozmo SDK drive_to_charger example script
# and raproenca's modifications of same.
#
# Additional modifications by Banteel to streamline the two 90 degree turns in one simple
# command that is linked to position.angle_z of object "charger" which contains all the info.
# rewritten to support battery/charge states and all kinds of bells and whistles by AcidZebra
#
# The default Low Battery Level for Cozmo is 3.65. For testing pursposes I have set mine
# to 3.88 so Cozmo gets on the dock more often. Please feel free to set both lines to 3.65
#
#import required functions
import sys, os, datetime, random, time, math, re, threading
##import logging
import asyncio, cozmo, cozmo.objects, cozmo.util, cozmo.world
from cozmo.util import Angle, degrees, distance_mm, speed_mmps, pose_z_angle, Pose
from cozmo.objects import CustomObject, CustomObjectMarkers, CustomObjectTypes, LightCube
from cozmo.robot_alignment import RobotAlignmentTypes
from cozmo import connect_on_loop
from asyncio import AbstractEventLoop
#external libraries used for camera annotation
#you will need to add these using pip/pip3
from PIL import ImageDraw, ImageFont
import numpy as np
global robot, charger, freeplay, robotvolume, found_object, custom_objects, marker_time, use_cubes, use_walls
global use_scheduler, scheduled_days, scheduled_time
robot = cozmo.robot.Robot
custom_objects=[]
found_object=None
freeplay=0
marker_time=0
scheduled_days="None"
scheduled_time=0
#
#============================
# CONFIGURABLE VARIABLES HERE
#============================
#
# BATTERY VOLTAGE THRESHOLDS
#
# lowbatvolt - when voltage drops below this Cozmo will start looking for his charger
# highbatvolt - when cozmo comes off your charger fully charge, this value will self-calibrate
# maxbatvolt - the maximum battery level as recorded when cozmo is on charger but no longer charging
# tweak lowbatvolt to suit your cozmo. default value is 3.65
lowbatvolt = 3.65
#highbatvolt= 4.04 - currently not used
#maxbatvolt = 4.54 - currently not used
#
# COZMO'S VOICE VOLUME
# what volume Cozmo should play sounds at, value between 0 and 1
robotvolume = 0.05
#
# CUBE USAGE
#
# whether or not to activate the cubes (saves battery if you don't)
# I almost always leave this off, he will still stack them and mess around with them
# some games like "block guard dog" will not come up unless the blocks are active
#
# value of 0: cubes off & cube's lights off
# value of 1: cubes on & enables all games
# value of 2: cubes on & cube's freeplay lights on & in-schedule breathing lights off
# value of 3: cubes on & cube's freeplay lights on & in-schedule breathing lights on
# value between 0 and 3
use_cubes = 3
#
# MARKER WALLS USAGE
#
# whether or not you are using printed out markers for walls on your play field
# if you are using walls, you will likely need to configure wall sizes to your play area
# values between 0 and 1
use_walls = 1
#
# SCHEDULER USAGE
#
# whether or not to use the schedule to define allowed "play times"
# this code is a bit rough, use at your own risk
# value between 0 and 1
use_scheduler = 1
#
# SCHEDULE START & STOP SETTING IN 24HR TIME FORMAT ex. 0 to 23
#
if use_scheduler == 1:
# Initialize Scheduler Variables
global wkDS, wkDSm, wkDE, wkDEm, wkNS, wkNSm, wkNE, wkNEm, wkEDS, wkEDSm, wkEDE, wkEDEm, wkENS, wkENSm, wkENE, wkENEm, wday
# Week Days
wkDS = 7 # Week (D)ay's (S)tarting time hour, default is 7AM
wkDSm = 15 # Week (D)ay's (S)tarting time minute
wkDE = 8 # Week (D)ay's (E)nding time hour, default is 8AM
wkDEm = 35 # Week (D)ay's (E)nding time minute
# Week Day Nights
wkNS = 15 # Week (N)ight's (S)tarting time hour, default is 3PM
wkNSm = 35 # Week (N)ight's (S)tarting time minute
wkNE = 23 # Week (N)ight's (E)nding time hour, default is 11PM
wkNEm = 15 # Week (N)ight's (E)nding time minute
# Week End Days
wkEDS = 9 # Week(E)nd (D)ay's (S)tarting time hour, default is 9AM
wkEDSm = 0 # Week(E)nd (D)ay's (S)tarting time minute
wkEDE = 12 # Week(E)nd (D)ay's (E)nding time hour, default is 12PM
wkEDEm = 20 # Week(E)nd (D)ay's (E)nding time minute
# Week End Nights
wkENS = 15 # Week(E)nd (N)ight's (S)tarting time hour, default is 3PM
wkENSm = 35 # Week(E)nd (N)ight's (S)tarting time minute
wkENE = 23 # Week(E)nd (N)ight's (E)nding time hour, default is 11PM
wkENEm = 58 # Week(E)nd (N)ight's (E)nding time minute
#
#COZMO SCHEDULER DEFAULT TIME SETTINGS:
## Week Days
#wkDS = 7 # Week (D)ay's (S)tarting time hour, default is 7AM
#wkDSm = 15 # Week (D)ay's (S)tarting time minute
#wkDE = 8 # Week (D)ay's (E)nding time hour, default is 8AM
#wkDEm = 35 # Week (D)ay's (E)nding time minute
#
## Week Day Nights
#wkNS = 15 # Week (N)ight's (S)tarting time hour, default is 3PM
#wkNSm = 35 # Week (N)ight's (S)tarting time minute
#wkNE = 23 # Week (N)ight's (E)nding time hour, default is 11PM
#wkNEm = 15 # Week (N)ight's (E)nding time minute
#
## Week End Days
#wkEDS = 9 # Week(E)nd (D)ay's (S)tarting time hour, default is 9AM
#wkEDSm = 0 # Week(E)nd (D)ay's (S)tarting time minute
#wkEDE = 12 # Week(E)nd (D)ay's (E)nding time hour, default is 12PM
#wkEDEm = 20 # Week(E)nd (D)ay's (E)nding time minute
#
## Week End Nights
#wkENS = 15 # Week(E)nd (N)ight's (S)tarting time hour, default is 3PM
#wkENSm = 35 # Week(E)nd (N)ight's (S)tarting time minute
#wkENE = 23 # Week(E)nd (N)ight's (E)nding time hour, default is 11PM
#wkENEm = 58 # Week(E)nd (N)ight's (E)nding time minute
#
## define goto_chargermarker_pose behaviour
def goto_chargermarker_pose(robot: robot):
global charger, custom_objects, found_object
counter=0
while robot.world.charger == None:
if str(found_object.object_type) == "CustomObjectTypes.CustomType01" and charger==None:
robot.stop_all_motors()
robot.clear_idle_animation()
robot.abort_all_actions(log_abort_messages=False)
try:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: custom object found, traveling, battery %s" % str(round(robot.battery_voltage, 2)))
robot.go_to_pose(pose_z_angle(found_object.pose.position.x, found_object.pose.position.y, 0, angle_z=degrees(found_object.pose.rotation.angle_z.degrees)), in_parallel=False, num_retries=2).wait_for_completed()
except:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: failed to goto pose, battery %s" % str(round(robot.battery_voltage, 2)))
robot.wait_for_all_actions_completed()
try:
robot.turn_in_place(degrees(found_object.pose.rotation.angle_z.degrees), num_retries=2, accel=degrees(80), angle_tolerance=None, is_absolute=True).wait_for_completed()
except:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: failed to turn in place, battery %s" % str(round(robot.battery_voltage, 2)))
try:
robot.set_head_angle(degrees(0)).wait_for_completed()
except:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: failed to set head angle, battery %s" % str(round(robot.battery_voltage, 2)))
robot.wait_for_all_actions_completed()
time.sleep(3)
if robot.world.charger != None:
charger = robot.world.charger
robot.world.charger = None
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: found charger after goto chargermarker, battery %s" % str(round(robot.battery_voltage, 2)))
try:
robot.turn_in_place(degrees(charger.pose.rotation.angle_z.degrees), num_retries=2, accel=degrees(80), angle_tolerance=None, is_absolute=True).wait_for_completed()
except:
print("State: failed to turn in place, battery %s" % str(round(robot.battery_voltage, 2)))
try:
robot.drive_straight(distance_mm(-120), speed_mmps(40)).wait_for_completed()
robot.wait_for_all_actions_completed()
except:
print("State: failed to drive straight, battery %s" % str(round(robot.battery_voltage, 2)))
try:
action = robot.go_to_object(charger, distance_mm(100), RobotAlignmentTypes.LiftPlate, num_retries=3)
action.wait_for_completed()
robot.wait_for_all_actions_completed()
except:
print("State: failed to goto object, battery %s" % str(round(robot.battery_voltage, 2)))
try:
action = robot.go_to_object(charger, distance_mm(80), RobotAlignmentTypes.LiftPlate, num_retries=3)
action.wait_for_completed()
robot.wait_for_all_actions_completed()
except:
print("State: failed to goto object, battery %s" % str(round(robot.battery_voltage, 2)))
try:
action = robot.go_to_object(charger, distance_mm(60), RobotAlignmentTypes.LiftPlate, num_retries=3)
action.wait_for_completed()
robot.wait_for_all_actions_completed()
except:
print("State: failed to goto object, battery %s" % str(round(robot.battery_voltage, 2)))
finally:
break
time.sleep(1)
if not robot.world.charger:
try:
robot.turn_in_place(degrees(found_object.pose.rotation.angle_z.degrees), num_retries=2, accel=degrees(80), angle_tolerance=None, is_absolute=True).wait_for_completed()
except:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: failed to turn in place, battery %s" % str(round(robot.battery_voltage, 2)))
try:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: can't see charger, backup a bit, battery %s" % str(round(robot.battery_voltage, 2)))
robot.drive_straight(distance_mm(-80), speed_mmps(40)).wait_for_completed()
robot.wait_for_all_actions_completed()
except:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: failed to drive straight, battery %s" % str(round(robot.battery_voltage, 2)))
try:
robot.turn_in_place(degrees(found_object.pose.rotation.angle_z.degrees), num_retries=2, accel=degrees(80), angle_tolerance=None, is_absolute=True).wait_for_completed()
except:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: failed to turn in place, battery %s" % str(round(robot.battery_voltage, 2)))
robot.wait_for_all_actions_completed()
time.sleep(2)
try:
charger = robot.world.wait_for_observed_charger(timeout=3, include_existing=True)
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: found charger after backup!, battery %s" % str(round(robot.battery_voltage, 2)))
break
except asyncio.TimeoutError:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: i don't see the charger, battery %s" % str(round(robot.battery_voltage, 2)))
time.sleep(0.5)
if not robot.world.charger:
try:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: can't see charger, backup a bit more, battery %s" % str(round(robot.battery_voltage, 2)))
robot.drive_straight(distance_mm(-60), speed_mmps(40)).wait_for_completed()
robot.wait_for_all_actions_completed()
except:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: failed to drive straight, battery %s" % str(round(robot.battery_voltage, 2)))
try:
robot.turn_in_place(degrees(found_object.pose.rotation.angle_z.degrees), num_retries=2, accel=degrees(80), angle_tolerance=None, is_absolute=True).wait_for_completed()
except:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: failed to turn in place, battery %s" % str(round(robot.battery_voltage, 2)))
try:
charger = robot.world.wait_for_observed_charger(timeout=3, include_existing=True)
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: found charger after backup!, battery %s" % str(round(robot.battery_voltage, 2)))
break
except asyncio.TimeoutError:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: i still don't see the charger, battery %s" % str(round(robot.battery_voltage, 2)))
time.sleep(1)
robot.set_head_angle(degrees(10)).wait_for_completed()
robot.wait_for_all_actions_completed()
time.sleep(1)
if found_object.is_visible==False:
try:
robot.turn_in_place(degrees(found_object.pose.rotation.angle_z.degrees), num_retries=2, accel=degrees(80), angle_tolerance=None, is_absolute=True).wait_for_completed()
except:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: failed to turn in place, battery %s" % str(round(robot.battery_voltage, 2)))
try:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: can't see chargermarker, backup a lot, battery %s" % str(round(robot.battery_voltage, 2)))
robot.drive_straight(distance_mm(-100), speed_mmps(40)).wait_for_completed()
except:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: failed to drive straight, battery %s" % str(round(robot.battery_voltage, 2)))
try:
charger = robot.world.wait_for_observed_charger(timeout=3, include_existing=True)
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: found charger after backup!, battery %s" % str(round(robot.battery_voltage, 2)))
break
except asyncio.TimeoutError:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: did not find charger, try again, battery %s" % str(round(robot.battery_voltage, 2)))
robot.wait_for_all_actions_completed()
time.sleep(3)
if charger == None and robot.world.charger == None:
counter+=1
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: chargermarker goto retry: "+str(counter))
if counter > 1:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: chargermarker goto failed, resetting, battery %s" % str(round(robot.battery_voltage, 2)))
break
custom_objects = None
found_object = None
## define look for charger and goto routine
def find_charger_and_goto(robot: robot):
global charger, freeplay, found_object, custom_objects, temp_object, marker_time, lowbatvolt, scheduled_time
# we don't know where the charger is
if not charger:
# we will look around in place for the charger for 30 seconds
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: look around for charger, battery %s" % str(round(robot.battery_voltage, 2)))
robot.play_anim_trigger(cozmo.anim.Triggers.SparkIdle, ignore_body_track=True).wait_for_completed()
robot.set_head_angle(degrees(0)).wait_for_completed()
robot.move_lift(-3)
robot.wait_for_all_actions_completed()
time.sleep(0.1)
robot.start_behavior(cozmo.behavior.BehaviorTypes.LookAroundInPlace)
current_time = time.time()
end_time = time.time() + 35.0
while current_time < end_time:
if found_object != None and str(found_object.object_type) == "CustomObjectTypes.CustomType01":
robot.start_behavior(cozmo.behavior.BehaviorTypes.LookAroundInPlace).stop()
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: chargermarker still known, battery %s" % str(round(robot.battery_voltage, 2)))
goto_chargermarker_pose(robot)
custom_objects = None
break
try:
charger = robot.world.wait_for_observed_charger(timeout=0.1, include_existing=True)
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: found charger in lookaround!, battery %s" % str(round(robot.battery_voltage, 2)))
if charger != None:
robot.start_behavior(cozmo.behavior.BehaviorTypes.LookAroundInPlace).stop()
try:
robot.turn_in_place(degrees(charger.pose.rotation.angle_z.degrees), accel=degrees(80), angle_tolerance=None, is_absolute=True, num_retries=2).wait_for_completed()
finally:
pass
try:
robot.drive_straight(distance_mm(-70), speed_mmps(50)).wait_for_completed()
finally:
break
except asyncio.TimeoutError:
pass
time.sleep(0.01)
try:
custom_objects = robot.world.wait_until_observe_num_objects(num=1, object_type=CustomObject, timeout=0.1, include_existing=True)
except asyncio.TimeoutError:
pass
finally:
time.sleep(0.1)
if custom_objects != None:
if len(custom_objects) > 0 and str(custom_objects[0].object_type) == "CustomObjectTypes.CustomType01":
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: found chargermarker in lookaround!, battery %s" % str(round(robot.battery_voltage, 2)))
robot.start_behavior(cozmo.behavior.BehaviorTypes.LookAroundInPlace).stop()
found_object = custom_objects[0]
custom_objects=None
break
if custom_objects != None:
custom_objects=None
if current_time > end_time:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: lookaround time ended, didn't find charger or marker, battery %s" % str(round(robot.battery_voltage, 2)))
robot.start_behavior(cozmo.behavior.BehaviorTypes.LookAroundInPlace).stop()
break
current_time = time.time()
time.sleep(0.1)
# lookaround is stopped
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: stop lookaround, battery %s" % str(round(robot.battery_voltage, 2)))
#robot.start_behavior(cozmo.behavior.BehaviorTypes.LookAroundInPlace).stop()
robot.wait_for_all_actions_completed()
time.sleep(1)
if found_object != None and charger==None:
time.sleep(1)
goto_chargermarker_pose(robot)
custom_objects=None
time.sleep(1)
# Docking routines & fallback routines are here
if charger:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: docking mode, moving to charger, battery %s" % str(round(robot.battery_voltage, 2)))
while (robot.is_on_charger == 0):
# check to make sure we didn't get here from a battery spike
if (robot.battery_voltage > lowbatvolt + 0.03) and (scheduled_time == 1):
break
# Yes! Attempt to drive near to the charger, and then stop.
robot.play_anim_trigger(cozmo.anim.Triggers.CodeLabChatty, ignore_lift_track=True, ignore_body_track=True, ignore_head_track=True).wait_for_completed()
robot.wait_for_all_actions_completed()
time.sleep(1)
robot.move_lift(-3)
robot.set_head_angle(degrees(0)).wait_for_completed()
# If you are running Cozmo on carpet, try turning these num_retries up to 4 or 5
try:
action = robot.go_to_object(charger, distance_mm(160), RobotAlignmentTypes.LiftPlate, num_retries=2)
action.wait_for_completed()
finally:
pass
try:
action = robot.go_to_object(charger, distance_mm(120), RobotAlignmentTypes.LiftPlate, num_retries=2)
action.wait_for_completed()
finally:
pass
try:
action = robot.go_to_object(charger, distance_mm(100), RobotAlignmentTypes.LiftPlate, num_retries=3)
action.wait_for_completed()
finally:
pass
try:
action = robot.go_to_object(charger, distance_mm(80), RobotAlignmentTypes.LiftPlate, num_retries=3)
action.wait_for_completed()
finally:
pass
try:
action = robot.go_to_object(charger, distance_mm(60), RobotAlignmentTypes.LiftPlate, num_retries=3)
action.wait_for_completed()
finally:
pass
time.sleep(2)
try:
robot.turn_in_place(degrees(charger.pose.rotation.angle_z.degrees), accel=degrees(80), angle_tolerance=None, is_absolute=True, num_retries=2).wait_for_completed()
finally:
pass
try:
robot.drive_straight(distance_mm(-70), speed_mmps(50)).wait_for_completed()
finally:
pass
try:
action = robot.go_to_object(charger, distance_mm(90), RobotAlignmentTypes.LiftPlate, num_retries=3)
action.wait_for_completed()
finally:
pass
try:
action = robot.go_to_object(charger, distance_mm(60), RobotAlignmentTypes.LiftPlate, num_retries=3)
action.wait_for_completed()
finally:
pass
try:
action = robot.go_to_object(charger, distance_mm(40), RobotAlignmentTypes.LiftPlate, num_retries=3)
action.wait_for_completed()
finally:
pass
# we should be right in front of the charger, can we see it?
time.sleep(1)
if (charger.is_visible == False):
# we know where the charger is but can't see it
# is robot flipped over or picked up?
try:
if robot.is_picked_up == True:
robot.stop_all_motors()
robot.abort_all_actions(False)
robot.clear_idle_animation()
robot.wait_for_all_actions_completed()
time.sleep(1)
charger = None
robot.world.charger = None
temp_object = None
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: robot delocalized during docking, resetting, battery %s" % str(round(robot.battery_voltage, 2)))
break
finally:
pass
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: can't see charger, position is still known, battery %s" % str(round(robot.battery_voltage, 2)))
robot.play_anim_trigger(cozmo.anim.Triggers.CodeLabSurprise, ignore_body_track=True, ignore_head_track=True).wait_for_completed()
robot.set_head_angle(degrees(0)).wait_for_completed()
robot.wait_for_all_actions_completed()
time.sleep(2)
#os.system('cls' if os.name == 'nt' else 'clear')
print(str(charger))
# charger is not in front of us, backup and try again
try:
robot.turn_in_place(degrees(charger.pose.rotation.angle_z.degrees), accel=degrees(80), angle_tolerance=None, is_absolute=True, num_retries=2).wait_for_completed()
finally:
pass
try:
action = robot.drive_straight(distance_mm(-140), speed_mmps(40))
action.wait_for_completed()
finally:
pass
try:
action = robot.go_to_object(charger, distance_mm(110), RobotAlignmentTypes.LiftPlate, num_retries=2)
action.wait_for_completed()
finally:
pass
try:
action = robot.go_to_object(charger, distance_mm(80), RobotAlignmentTypes.LiftPlate, num_retries=2)
action.wait_for_completed()
finally:
pass
robot.wait_for_all_actions_completed()
robot.turn_in_place(degrees(charger.pose.rotation.angle_z.degrees), accel=degrees(80), angle_tolerance=None, is_absolute=True, num_retries=2).wait_for_completed()
robot.drive_straight(distance_mm(-50), speed_mmps(50)).wait_for_completed()
robot.wait_for_all_actions_completed()
time.sleep(1)
if (charger.is_visible == False):
# we don't know where the charger is, clear all locations
robot.play_anim_trigger(cozmo.anim.Triggers.ReactToPokeReaction, ignore_body_track=True, ignore_head_track=True, ignore_lift_track=True).wait_for_completed()
robot.drive_straight(distance_mm(-70), speed_mmps(50)).wait_for_completed()
robot.turn_in_place(degrees(charger.pose.rotation.angle_z.degrees), accel=degrees(80), angle_tolerance=None, is_absolute=True, num_retries=2).wait_for_completed()
robot.wait_for_all_actions_completed()
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: charger not found, clearing map, battery %s" % str(round(robot.battery_voltage, 2)))
charger = None
robot.world.charger = None
temp_object = None
time.sleep(1)
break
else:
break
robot.enable_all_reaction_triggers(False)
i = random.randint(1, 100)
if i >= 85:
robot.play_anim_trigger(cozmo.anim.Triggers.FeedingReactToShake_Normal, ignore_body_track=True, ignore_head_track=True).wait_for_completed()
robot.wait_for_all_actions_completed()
time.sleep(2)
# charger should be in front of us. Turn around, drive backwards, and dock
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: docking, battery %s" % str(round(robot.battery_voltage, 2)))
time.sleep(2.5)
if robot.is_animating:
robot.clear_idle_animation()
robot.abort_all_actions(log_abort_messages=True)
robot.wait_for_all_actions_completed()
robot.wait_for_all_actions_completed()
robot.turn_in_place(degrees(charger.pose.rotation.angle_z.degrees - 180), accel=degrees(80), angle_tolerance=None, is_absolute=True).wait_for_completed()
robot.wait_for_all_actions_completed()
time.sleep(0.1)
robot.play_anim_trigger(cozmo.anim.Triggers.CubePounceFake, ignore_body_track=True, ignore_lift_track=True, ignore_head_track=True).wait_for_completed()
robot.set_head_angle(degrees(0)).wait_for_completed()
robot.wait_for_all_actions_completed()
#robot.clear_idle_animation()
time.sleep(1)
backup_count = 0
while robot.is_on_charger == 0:
try:
robot.backup_onto_charger(max_drive_time=2)
backup_count+=1
time.sleep(0.4)
if robot.is_on_charger == 1:
print("State: Robot is on Charger, battery %s" % str(round(robot.battery_voltage, 2)))
robot.enable_all_reaction_triggers(False)
break
elif backup_count == 6:
robot.enable_all_reaction_triggers(False)
break
except robot.is_on_charger == 1:
robot.stop_all_motors()
print("State: Contact! Stop all motors, battery %s" % str(round(robot.battery_voltage, 2)))
robot.wait_for_all_actions_completed()
#try:
# robot.backup_onto_charger(max_drive_time=6)
#except robot.is_on_charger == 1:
# robot.stop_all_motors()
#finally:
# robot.enable_all_reaction_triggers(False)
#robot.wait_for_all_actions_completed()
#time.sleep(2)
#try:
# if robot.is_on_charger == 0:
# #os.system('cls' if os.name == 'nt' else 'clear')
# print("State: bumped into something, backup a bit more, battery %s" % str(round(robot.battery_voltage, 2)))
# robot.backup_onto_charger(max_drive_time=3)
#except robot.is_on_charger == 1:
# robot.stop_all_motors()
#finally:
# robot.enable_all_reaction_triggers(False)
# time.sleep(2)
robot.wait_for_all_actions_completed()
# check if we're now docked
if robot.is_on_charger:
# Yes! we're docked!
robot.play_anim("anim_sparking_success_02").wait_for_completed()
robot.set_head_angle(degrees(0)).wait_for_completed()
robot.wait_for_all_actions_completed()
time.sleep(1.5)
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: I am now docked, battery %s" % str(round(robot.battery_voltage, 2)))
robot.set_all_backpack_lights(cozmo.lights.off_light)
robot.play_anim("anim_gotosleep_getin_01").wait_for_completed()
robot.wait_for_all_actions_completed()
time.sleep(1)
robot.play_anim("anim_gotosleep_sleeping_01").wait_for_completed()
robot.wait_for_all_actions_completed()
time.sleep(1)
else:
# No, we missed. Drive forward, turn around, and try again
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: failed to dock with charger, battery %s" % str(round(robot.battery_voltage, 2)))
robot.play_anim_trigger(cozmo.anim.Triggers.AskToBeRightedRight, ignore_body_track=True).wait_for_completed()
#robot.move_lift(-3)
robot.set_head_angle(degrees(0)).wait_for_completed()
robot.wait_for_all_actions_completed()
time.sleep(0.5)
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: drive forward, turn around, and try again, battery %s" % str(round(robot.battery_voltage, 2)))
robot.turn_in_place(degrees(charger.pose.rotation.angle_z.degrees - 180), accel=degrees(80), angle_tolerance=None, is_absolute=True, num_retries=2).wait_for_completed()
robot.drive_straight(distance_mm(90), speed_mmps(90)).wait_for_completed()
robot.wait_for_all_actions_completed()
time.sleep(0.5)
robot.drive_straight(distance_mm(90), speed_mmps(90)).wait_for_completed()
robot.turn_in_place(degrees(charger.pose.rotation.angle_z.degrees), accel=degrees(80), angle_tolerance=None, is_absolute=True, num_retries=2).wait_for_completed()
robot.set_head_angle(degrees(0)).wait_for_completed()
robot.wait_for_all_actions_completed()
time.sleep(1)
if (charger.is_visible == False):
# we know where the charger is
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: can't see charger after turnaround, try again, battery %s" % str(round(robot.battery_voltage, 2)))
robot.play_anim_trigger(cozmo.anim.Triggers.CodeLabSurprise, ignore_body_track=True, ignore_head_track=True).wait_for_completed()
robot.set_head_angle(degrees(0)).wait_for_completed()
robot.wait_for_all_actions_completed()
#os.system('cls' if os.name == 'nt' else 'clear')
print(str(charger))
try:
action = robot.go_to_object(charger, distance_mm(110), RobotAlignmentTypes.LiftPlate, num_retries=2)
action.wait_for_completed()
finally:
pass
try:
action = robot.go_to_object(charger, distance_mm(80), RobotAlignmentTypes.LiftPlate, num_retries=2)
action.wait_for_completed()
finally:
pass
robot.turn_in_place(degrees(charger.pose.rotation.angle_z.degrees), accel=degrees(80), angle_tolerance=None, is_absolute=True, num_retries=2).wait_for_completed()
robot.wait_for_all_actions_completed()
if (charger.is_visible == False):
# we lost the charger, clearing all map variables
charger = None
robot.world.charger = None
temp_object = None
robot.play_anim_trigger(cozmo.anim.Triggers.ReactToPokeReaction, ignore_body_track=True, ignore_head_track=True, ignore_lift_track=True).wait_for_completed()
robot.drive_straight(distance_mm(-120), speed_mmps(50)).wait_for_completed()
robot.wait_for_all_actions_completed()
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: charger lost while docking, clearing map, battery %s" % str(round(robot.battery_voltage, 2)))
time.sleep(1)
break
if robot.world.charger != None:
charger = robot.world.charger
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: update charger location, battery %s" % str(round(robot.battery_voltage, 2)))
#os.system('cls' if os.name == 'nt' else 'clear')
print(str(charger))
robot.world.charger = None
else:
# we have not managed to find the charger. Falling back to freeplay.
charger = None
robot.play_anim_trigger(cozmo.anim.Triggers.ReactToPokeReaction, ignore_body_track=True, ignore_head_track=True, ignore_lift_track=True).wait_for_completed()
robot.wait_for_all_actions_completed()
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: charger unknown, fallback to freeplay for 90sec, battery %s" % str(round(robot.battery_voltage, 2)))
robot.enable_all_reaction_triggers(True)
robot.start_freeplay_behaviors()
#try freeplay for 90 seconds, if found charger finally stop freeplay
current_time = time.time()
end_time = time.time() + 95.0
while current_time < end_time:
if found_object != None and str(found_object.object_type) == "CustomObjectTypes.CustomType01":
robot.stop_freeplay_behaviors()
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: chargermarker still known, battery %s" % str(round(robot.battery_voltage, 2)))
goto_chargermarker_pose(robot)
custom_objects = None
break
try:
charger = robot.world.wait_for_observed_charger(timeout=0.1, include_existing=True)
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: found the charger in 90sec playtime!, battery %s" % str(round(robot.battery_voltage, 2)))
if charger != None:
robot.stop_freeplay_behaviors()
try:
robot.turn_in_place(degrees(charger.pose.rotation.angle_z.degrees), accel=degrees(80), angle_tolerance=None, is_absolute=True, num_retries=2).wait_for_completed()
finally:
pass
try:
robot.drive_straight(distance_mm(-70), speed_mmps(50)).wait_for_completed()
finally:
break
except asyncio.TimeoutError:
pass
time.sleep(0.01)
try:
custom_objects = robot.world.wait_until_observe_num_objects(num=1, object_type=CustomObject, timeout=0.1, include_existing=True)
except asyncio.TimeoutError:
pass
finally:
time.sleep(0.1)
if custom_objects != None:
if len(custom_objects) > 0 and str(custom_objects[0].object_type) == "CustomObjectTypes.CustomType01":
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: found the chargermarker in 90sec playtime!, battery %s" % str(round(robot.battery_voltage, 2)))
robot.stop_freeplay_behaviors()
found_object = custom_objects[0]
custom_objects=None
break
if custom_objects != None:
custom_objects=None
if time.time() > end_time:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: freeplay time ended, didn't find charger or marker, battery %s" % str(round(robot.battery_voltage, 2)))
robot.stop_freeplay_behaviors()
break
current_time = time.time()
time.sleep(0.1)
#after 90 seconds end freeplay
robot.set_needs_levels(1, 1, 1)
robot.world.disconnect_from_cubes()
time.sleep(3)
robot.wait_for_all_actions_completed()
time.sleep(1)
if found_object != None and charger==None:
time.sleep(1)
goto_chargermarker_pose(robot)
custom_objects=None
time.sleep(1)
#
# Cozmo's Scheduler resting time
#
def cozmo_resting(robot: robot):
if (robot.is_on_charger == 1) and (robot.is_charging == 1):
# In here we make Cozmo do on or off Charger things while Charging for fun
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: charging, waiting for scheduled playtime, battery %s" % str(round(robot.battery_voltage, 2)))
i = random.randint(1, 100)
if i >= 97:
robot.play_anim("anim_guarddog_fakeout_02").wait_for_completed()
elif i >= 85:
robot.play_anim("anim_gotosleep_sleeploop_01").wait_for_completed()
time.sleep(3)
robot.set_all_backpack_lights(cozmo.lights.green_light)
time.sleep(3)
robot.set_all_backpack_lights(cozmo.lights.off_light)
elif (robot.is_on_charger == 1) and (robot.is_charging == 0):
# In here we make Cozmo do on or off Charger things while Charged for fun
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: Charged! waiting for scheduled playtime, battery %s" % str(round(robot.battery_voltage, 2)))
i = random.randint(1, 100)
if i >= 97:
robot.play_anim("anim_guarddog_fakeout_02").wait_for_completed()
elif i >= 85:
robot.play_anim("anim_gotosleep_sleeploop_01").wait_for_completed()
time.sleep(3)
robot.set_all_backpack_lights(cozmo.lights.green_light)
time.sleep(3)
robot.set_all_backpack_lights(cozmo.lights.off_light)
elif (robot.is_on_charger == 0) and (robot.is_charging == 0) and scheduled_days == "Resting":
robot.stop_freeplay_behaviors()
find_charger_and_goto(robot)
#
# Scheduler
#
def scheduler(robot: robot):
global use_scheduler, nowtime, wday, scheduled_days, scheduled_time
global wkDS, wkDSm, wkDE, wkDEm, wkNS, wkNSm, wkNE, wkNEm, wkEDS, wkEDSm, wkEDE, wkEDEm, wkENS, wkENSm, wkENE, wkENEm
wday = nowtime.tm_wday # 0 is Monday, 6 is Sunday
#TempTime = datetime.datetime.now().timetuple()
# Display Time Tuple for scripting usage purposes
#os.system('cls' if os.name == 'nt' else 'clear')
#print("State: Full timetuple() is: "+str(nowtime))
while True:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: Scheduled days: "+str(scheduled_days)+", battery %s" % str(round(robot.battery_voltage, 2)))
#weekday mornings
if (wday < 5 and nowtime.tm_hour > wkDS or wday < 5 and (wkDE < wkDS and nowtime.tm_hour > wkDS or nowtime.tm_hour == wkDS and nowtime.tm_min >= wkDSm)) and (nowtime.tm_hour < wkDE or wkDE < wkDS and nowtime.tm_hour > wkDE or nowtime.tm_hour == wkDE and nowtime.tm_min <= wkDEm):
scheduled_days = "WeekDayMorn"
scheduled_time = 1
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: Weekday Morning Time is: "+str(nowtime.tm_hour)+":"+str(nowtime.tm_min)+", battery %s" % str(round(robot.battery_voltage, 2)))
cozmo_unleashed(robot)
#weekday evenings
elif (wday < 5 and nowtime.tm_hour > wkNS or wday < 5 and (wkNE < wkNS and nowtime.tm_hour > wkNS or nowtime.tm_hour == wkNS and nowtime.tm_min >= wkNSm)) and (nowtime.tm_hour < wkNE or wkNE < wkNS and nowtime.tm_hour > wkNE or nowtime.tm_hour == wkNE and nowtime.tm_min <= wkNEm):
scheduled_days = "WeekDayEve"
scheduled_time = 1
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: Weekday Night Time is: "+str(nowtime.tm_hour)+":"+str(nowtime.tm_min)+", battery %s" % str(round(robot.battery_voltage, 2)))
cozmo_unleashed(robot)
#weekend mornings
elif (wday >= 5 and nowtime.tm_hour > wkEDS or wday >= 5 and (wkEDS < wkEDE and nowtime.tm_hour > wkEDS or nowtime.tm_hour == wkEDS and nowtime.tm_min >= wkEDSm)) and (nowtime.tm_hour < wkEDE or wkEDE < wkEDS and nowtime.tm_hour > wkEDE or nowtime.tm_hour == wkEDE and nowtime.tm_min <= wkEDEm):
scheduled_days = "WeekEndMorn"
scheduled_time = 1
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: Weekend Morning Time is: "+str(nowtime.tm_hour)+":"+str(nowtime.tm_min)+", battery %s" % str(round(robot.battery_voltage, 2)))
cozmo_unleashed(robot)
#weekend evenings
elif (wday >= 5 and nowtime.tm_hour > wkENS or wday >= 5 and (wkENS < wkENE and nowtime.tm_hour > wkENS or nowtime.tm_hour == wkENS and nowtime.tm_min >= wkENSm)) and (nowtime.tm_hour < wkENE or wkENE < wkENS and nowtime.tm_hour > wkENE or nowtime.tm_hour == wkENE and nowtime.tm_min <= wkENEm):
scheduled_days = "WeekEndEve"
scheduled_time = 1
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: Weekend Evening Time is: "+str(nowtime.tm_hour)+":"+str(nowtime.tm_min)+", battery %s" % str(round(robot.battery_voltage, 2)))
cozmo_unleashed(robot)
else:
nowtime = datetime.datetime.now().timetuple()
scheduled_days = "Resting"
scheduled_time = 0
cozmo_resting(robot)
#
#
# main program and loops
def cozmo_unleashed(robot: robot):
global charger, freeplay, robotvolume, found_object, custom_objects, temp_object, marker_time, use_walls, use_cubes
global use_scheduler, nowtime, wday, scheduled_days, scheduled_time
if use_scheduler == 1:
global wkDS, wkDSm, wkDE, wkDEm, wkNS, wkNSm, wkNE, wkNEm, wkEDS, wkEDSm, wkEDE, wkEDEm, wkENS, wkENSm, wkENE, wkENEm
if scheduled_days=="None" or use_scheduler == 0:
#
# DEFINING MARKERS
#
# 1st 2 numbers are the width/height of the paper the printed marker is on
# for the 1st dimension: measure the side of the width/height, from the printed marker's edge, then
# multiply it by 2 then add it to the 2nd dimension
# 2nd 2 numbers are the width/height of the printed marker on the paper
# I suggest using a ruler to measure these dimensions, by the millimeter, after you print & cut them to get exact numbers
# define the chargermarker for the dock
robot.world.define_custom_wall(CustomObjectTypes.CustomType01, CustomObjectMarkers.Hexagons2, 62, 62, 40, 40, True)
# these define the 4 walls of my play field, it helps Cozmo not bump into the walls
# you can set the use_walls variable at the top of the script to 0 if you are not using walls
if use_walls >= 1:
robot.world.define_custom_wall(CustomObjectTypes.CustomType02, CustomObjectMarkers.Diamonds2, 800, 90, 40, 40, True)
robot.world.define_custom_wall(CustomObjectTypes.CustomType03, CustomObjectMarkers.Diamonds3, 800, 90, 40, 40, True)
robot.world.define_custom_wall(CustomObjectTypes.CustomType04, CustomObjectMarkers.Diamonds4, 550, 90, 40, 40, True)
robot.world.define_custom_wall(CustomObjectTypes.CustomType05, CustomObjectMarkers.Diamonds5, 700, 90, 40, 40, True)
robot.world.charger = None
charger = None
found_object=None
temp_object=None
custom_objects=[]
if use_scheduler == 1:
nowtime = datetime.datetime.now().timetuple()
robot.wait_for_all_actions_completed()
robot.clear_idle_animation()
robot.stop_all_motors()
robot.abort_all_actions(log_abort_messages=False)
robot.enable_all_reaction_triggers(False)
robot.enable_stop_on_cliff(True)
robot.world.auto_disconnect_from_cubes_at_end(True)
robot.set_robot_volume(robotvolume)
time.sleep(1)
# cube_lights(enable=True) if you are using freeplay lights, set False to save battery
if use_cubes >= 2:
robot.enable_freeplay_cube_lights(enable=True)
time.sleep(2)
while True:
#State 1: on charger, charging
if (robot.is_on_charger == 1) and (robot.is_charging == 1):
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: charging, battery %s" % str(round(robot.battery_voltage, 2)))
freeplay=0
if scheduled_time == 1:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: charging, in scheduled playtime, battery %s" % str(round(robot.battery_voltage, 2)))
else:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: charging, battery %s" % str(round(robot.battery_voltage, 2)))
i = random.randint(1, 100)
if i >= 97:
robot.play_anim("anim_guarddog_fakeout_02").wait_for_completed()
robot.wait_for_all_actions_completed()
elif i >= 85:
robot.play_anim("anim_gotosleep_sleeploop_01").wait_for_completed()
robot.wait_for_all_actions_completed()
time.sleep(1.5)
robot.set_all_backpack_lights(cozmo.lights.green_light)
time.sleep(1.5)
robot.set_all_backpack_lights(cozmo.lights.off_light)
#State 2: on charger, fully charged
if (robot.is_on_charger == 1) and (robot.is_charging == 0) and (scheduled_days != "Resting") and (scheduled_time == 1 or use_scheduler == 0):
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: charged, battery %s" % str(round(robot.battery_voltage, 2)))
robot.set_needs_levels(1, 1, 1)
robot.set_all_backpack_lights(cozmo.lights.off_light)
robot.play_anim("anim_launch_altwakeup_01").wait_for_completed()
robot.wait_for_all_actions_completed()
time.sleep(2)
robot.drive_off_charger_contacts(num_retries=3, in_parallel=False).wait_for_completed()
robot.move_lift(-3)
try:
if (robot.is_on_charger == 1):
robot.drive_straight(distance_mm(80), speed_mmps(25), num_retries=2).wait_for_completed()
finally:
pass
robot.enable_all_reaction_triggers(True)
time.sleep(2)
robot.wait_for_all_actions_completed()
elif use_scheduler == 1 and scheduled_days == "None":
scheduler(robot)
#State 3: not on charger, good time play battery | default low battery is 3.65
if (robot.battery_voltage > lowbatvolt) and (robot.is_on_charger == 0) and (scheduled_time == 1 or use_scheduler == 0):
if use_scheduler == 1 and scheduled_days == "None":
scheduler(robot)
elif freeplay == 0:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: turn on good time play battery %s" % str(round(robot.battery_voltage, 2)))
robot.clear_idle_animation()
robot.abort_all_actions(log_abort_messages=False)
if use_cubes == 1:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: turn on cubes %s" % str(round(robot.battery_voltage, 2)))
robot.world.connect_to_cubes()
time.sleep(5)
elif use_cubes >= 2:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: turn on cubes and freeplay lights %s" % str(round(robot.battery_voltage, 2)))
robot.enable_freeplay_cube_lights(True)
robot.world.connect_to_cubes()
time.sleep(5)
robot.enable_all_reaction_triggers(True)
robot.start_freeplay_behaviors()
freeplay=1
elif freeplay == 1 and robot.battery_voltage > lowbatvolt - 0.03:
if use_cubes >= 2:
robot.enable_freeplay_cube_lights(True)
pass
if robot.is_picked_up == True:
charger = None
robot.world.charger = None
temp_object = None
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: robot delocalized during freeplay, resetting everything, battery %s" % str(round(robot.battery_voltage, 2)))
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: good battery playtime, battery %s" % str(round(robot.battery_voltage, 2)))
time.sleep(3)
#State 4: not on charger, low battery | default low battery is 3.65
if (robot.battery_voltage <= lowbatvolt) and (robot.is_on_charger == 0):
if freeplay == 1:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: turn off good battery freeplay, battery %s" % str(round(robot.battery_voltage, 2)))
robot.stop_all_motors()
robot.clear_idle_animation()
robot.enable_all_reaction_triggers(False)
robot.abort_all_actions(log_abort_messages=False)
robot.wait_for_all_actions_completed()
time.sleep(1)
robot.stop_freeplay_behaviors()
if use_cubes == 1 or use_cubes == 3:
robot.world.disconnect_from_cubes()
time.sleep(5)
elif use_cubes == 2:
robot.enable_freeplay_cube_lights(False)
robot.world.disconnect_from_cubes()
time.sleep(5)
freeplay=0
robot.play_anim_trigger(cozmo.anim.Triggers.NeedsMildLowEnergyRequest, ignore_body_track=True).wait_for_completed()
robot.wait_for_all_actions_completed()
time.sleep(2)
robot.set_all_backpack_lights(cozmo.lights.blue_light)
robot.set_head_angle(degrees(0)).wait_for_completed()
robot.move_lift(-3)
robot.wait_for_all_actions_completed()
time.sleep(0.1)
#robot.drive_straight(distance_mm(-30), speed_mmps(50)).wait_for_completed()
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: low battery, finding charger, battery %s" % str(round(robot.battery_voltage, 2)))
robot.enable_all_reaction_triggers(True)
# charger location search
# see if we already know where the charger is
if charger != None:
#we know where the charger is
robot.move_lift(-3)
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: start docking loop, charger position known, battery %s" % str(round(robot.battery_voltage, 2)))
robot.play_anim_trigger(cozmo.anim.Triggers.CodeLabSurprise, ignore_body_track=True, ignore_head_track=True).wait_for_completed()
robot.set_head_angle(degrees(0)).wait_for_completed()
robot.wait_for_all_actions_completed()
time.sleep(0.01)
#os.system('cls' if os.name == 'nt' else 'clear')
print(str(charger))
if charger != None:
try:
action = robot.go_to_object(charger, distance_mm(110), RobotAlignmentTypes.LiftPlate, num_retries=3)
action.wait_for_completed()
finally:
pass
try:
action = robot.go_to_object(charger, distance_mm(80), RobotAlignmentTypes.LiftPlate, num_retries=3)
action.wait_for_completed()
finally:
pass
robot.turn_in_place(degrees(charger.pose.rotation.angle_z.degrees), accel=degrees(80), angle_tolerance=None, is_absolute=True).wait_for_completed()
robot.wait_for_all_actions_completed()
time.sleep(1)
elif found_object != None:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: start of loop, chargermarker known, battery %s" % str(round(robot.battery_voltage, 2)))
robot.play_anim_trigger(cozmo.anim.Triggers.CodeLabSurprise, ignore_body_track=True, ignore_head_track=True).wait_for_completed()
robot.set_head_angle(degrees(0)).wait_for_completed()
robot.wait_for_all_actions_completed()
time.sleep(0.01)
goto_chargermarker_pose(robot)
else:
# we know where the charger is but we have been delocalized
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: did not find charger or marker after clearing map, battery %s" % str(round(robot.battery_voltage, 2)))
if use_cubes == 1 or use_cubes == 3:
robot.world.disconnect_from_cubes()
time.sleep(4)
elif use_cubes == 2:
robot.enable_freeplay_cube_lights(enable=False)
robot.world.disconnect_from_cubes()
time.sleep(4)
## decide if we need to run find charger routines or not
find_charger_and_goto(robot)
## end of loop routines
if robot.is_picked_up == True:
charger = None
robot.world.charger = None
temp_object = None
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: robot delocalized during freeplay, resetting charger, battery %s" % str(round(robot.battery_voltage, 2)))
while temp_object == None:
try:
custom_objects = robot.world.wait_until_observe_num_objects(num=1, object_type=CustomObject, timeout=2, include_existing=True)
if len(custom_objects) > 0:
temp_object = custom_objects[0]
custom_objects=[]
if str(temp_object.object_type) != "CustomObjectTypes.CustomType01":
temp_object=None
finally:
if temp_object != None and str(temp_object.object_type) == "CustomObjectTypes.CustomType01":
if found_object == None:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: found chargermarker in freeplay, battery %s" % str(round(robot.battery_voltage, 2)))
found_object = temp_object
temp_object = None
break
if temp_object != None and found_object != None:
if temp_object.pose.is_comparable(found_object.pose) == True:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: updating chargermarker location, battery %s" % str(round(robot.battery_voltage, 2)))
found_object = temp_object
else:
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: chargermarker pose comparison failed, battery %s" % str(round(robot.battery_voltage, 2)))
temp_object = None
break
#time.sleep(0.5)
if robot.world.charger != None:
charger = robot.world.charger
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: updating charger location, battery %s" % str(round(robot.battery_voltage, 2)))
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: "+str(charger)+", battery %s" % str(round(robot.battery_voltage, 2)))
robot.world.charger = None
robot.clear_idle_animation()
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: program loop complete, battery %s" % str(round(robot.battery_voltage, 2)))
time.sleep(3)
if use_scheduler == 1:
nowtime = datetime.datetime.now().timetuple()
if (scheduled_days == "WeekDayMorn" and (nowtime.tm_hour <= wkDS and nowtime.tm_min <= wkDSm) or (wkDE < wkDS and nowtime.tm_hour <= wkDS and nowtime.tm_min <= wkDSm)) or (scheduled_days == "WeekDayMorn" and (nowtime.tm_hour >= wkDE and nowtime.tm_min >= wkDEm) or (wkDE < wkDS and nowtime.tm_hour >= wkDE and nowtime.tm_min >= wkDEm)):
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: Weekday Morning Schedule, battery %s" % str(round(robot.battery_voltage, 2)))
scheduler(robot)
elif (scheduled_days == "WeekDayEve" and (nowtime.tm_hour <= wkNS and nowtime.tm_min <= wkNSm) or (wkNE < wkNS and nowtime.tm_hour <= wkNS and nowtime.tm_min <= wkNSm)) or (scheduled_days == "WeekDayEve" and (nowtime.tm_hour >= wkNE and nowtime.tm_min >= wkNEm) or (wkNE < wkNS and nowtime.tm_hour >= wkNE and nowtime.tm_min >= wkNEm)):
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: Weekday Evening Schedule, battery %s" % str(round(robot.battery_voltage, 2)))
scheduler(robot)
elif (scheduled_days == "WeekEndMorn" and (nowtime.tm_hour <= wkEDS and nowtime.tm_min <= wkEDSm) or (wkEDE < wkEDS and nowtime.tm_hour <= wkEDS and nowtime.tm_min <= wkEDSm)) or (scheduled_days == "WeekEndMorn" and (nowtime.tm_hour >= wkEDE and nowtime.tm_min >= wkEDEm) or (wkEDE < wkEDS and nowtime.tm_hour >= wkEDE and nowtime.tm_min >= wkEDEm)):
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: Weekend Schedule, battery %s" % str(round(robot.battery_voltage, 2)))
scheduler(robot)
elif (scheduled_days == "WeekEndEve" and (nowtime.tm_hour <= wkENS and nowtime.tm_min <= wkENSm) or (wkENE < wkENS and nowtime.tm_hour <= wkENS and nowtime.tm_min <= wkENSm)) or (scheduled_days == "WeekEndEve" and (nowtime.tm_hour >= wkENE and nowtime.tm_min >= wkENEm) or (wkENE < wkENS and nowtime.tm_hour >= wkENE and nowtime.tm_min >= wkENEm)):
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: Weekend Schedule, battery %s" % str(round(robot.battery_voltage, 2)))
scheduler(robot)
elif scheduled_days == "Resting" and scheduled_time == 0:
if use_cubes == 3:
robot.enable_freeplay_cube_lights(enable=True)
if robot.is_on_charger == 0:
robot.stop_freeplay_behaviors()
time.sleep(3)
#os.system('cls' if os.name == 'nt' else 'clear')
print("State: Resting Time Schedule, Find Charger, battery %s" % str(round(robot.battery_voltage, 2)))
find_charger_and_goto(robot)
else:
scheduler(robot)
#if use_scheduler == 1:
# #os.system('cls' if os.name == 'nt' else 'clear')
# print("State: End of Loop, How did we get here?, battery %s" % str(round(robot.battery_voltage, 2)))
# break
#
#
# START THE SHOW!
#
#cozmo.robot.Robot.drive_off_charger_on_connect = False
#cozmo.run_program(cozmo_unleashed, use_viewer=True, force_viewer_on_top=True, show_viewer_controls=True, exit_on_connection_error=True)
# if you have freeglut in the same folder as this script you can change the above line to
#cozmo.run_program(cozmo_unleashed, use_viewer=True, use_3d_viewer=True, force_viewer_on_top=True, show_viewer_controls=True, exit_on_connection_error=True)
# which will give you remote control over Cozmo via WASD+QERF while the 3d window has focus
# --- Above ^^ is the common command for running the first def.
# --- Below -- is a script from acidzebra for loading the main program, that I will
# like to eventually use to turn into a SDK Loop that can stay running in an executed
# program so that if the WiFi disconnects & reconnects again, the SDK Loop will kick
# back in when it sees a phone with an open SDK connection again, without having to
# stop and restart the script manually.
# Run at your own RISK, using the AbstractEventLoop is dangerous.
def run(sdk_conn_loop):
global robot
'''The run method runs once the Cozmo SDK is connected.'''
robot = sdk_conn_loop.wait_for_robot(timeout=1)
try:
#cozmo_unleashed(robot)
# ^^ this above line ^^ is the original safest call to use
# this connect_on_loop seems to work, though i don't think it actually reconnects
# the phone to cozmo as i intended it to. i'm still working on that part
# this AbstractEventLoop line might cause issues, use at your own risk
#connect_on_loop(AbstractEventLoop.run_forever(cozmo_unleashed(robot)), sdk_conn_loop)
# this non-Abstract connect_on_loop is much safer, use this line below
connect_on_loop(cozmo_unleashed(robot), sdk_conn_loop)
except KeyboardInterrupt as k:
#os.system('cls' if os.name == 'nt' else 'clear')
print("")
#os.system('cls' if os.name == 'nt' else 'clear')
print("Exit requested by user")
SystemExit("Keyboard interrupt: %s" % k)
if __name__ == '__main__':
cozmo.setup_basic_logging()
cozmo.robot.Robot.drive_off_charger_on_connect = False # Cozmo can stay on charger for now
try:
cozmo.connect_with_tkviewer(run, force_on_top=True)
except cozmo.ConnectionError as e:
SystemExit("A connection error with viewer occurred: %s" % e)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment