Skip to content

Instantly share code, notes, and snippets.

@VictorTagayun
Forked from acidzebra/cozmo_unleashed.py
Created October 14, 2017 16:00
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save VictorTagayun/219aa7dab61af6efef0214437e5de55a to your computer and use it in GitHub Desktop.
Save VictorTagayun/219aa7dab61af6efef0214437e5de55a to your computer and use it in GitHub Desktop.
Attempting to create a perpetuum cozmobile
#!/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.
#
#
# cozmo_unleashed
#
# Script based on the Cozmo SDK drive_to_charger example script
# and raproenca's modifications of same.
# rewritten to support battery/charge states and all kinds of bells and whistles by acid zebra
#
import os
import datetime
import random
import time
import asyncio
import cozmo
from cozmo.util import degrees, distance_mm, speed_mmps
from cozmo.objects import CustomObject, CustomObjectMarkers, CustomObjectTypes
global freeplay
freeplay=0
# main program and loops
def cozmo_unleashed(robot: cozmo.robot.Robot):
global freeplay
robot.world.disconnect_from_cubes()
robot.enable_all_reaction_triggers(False)
robot.enable_stop_on_cliff(True)
robot.set_robot_volume(0.04)
os.system('cls' if os.name == 'nt' else 'clear')
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)))
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)
#State 2: on charger, fully charged
if (robot.is_on_charger == 1) and (robot.is_charging == 0):
os.system('cls' if os.name == 'nt' else 'clear')
print("State: charged, battery %s" % str(round(robot.battery_voltage, 2)))
robot.set_all_backpack_lights(cozmo.lights.off_light)
robot.play_anim("anim_launch_altwakeup_01").wait_for_completed()
robot.drive_off_charger_contacts().wait_for_completed()
robot.drive_off_charger_contacts().wait_for_completed()
robot.drive_off_charger_contacts().wait_for_completed()
time.sleep(2)
robot.move_lift(-3)
robot.drive_straight(distance_mm(50), speed_mmps(50)).wait_for_completed()
robot.drive_straight(distance_mm(100), speed_mmps(50)).wait_for_completed()
time.sleep(2)
#State 3: not on charger, good battery
if (robot.battery_voltage > 3.65) and (robot.is_on_charger == 0):
if freeplay==0:
robot.world.connect_to_cubes()
robot.enable_all_reaction_triggers(True)
robot.start_freeplay_behaviors()
freeplay=1
os.system('cls' if os.name == 'nt' else 'clear')
print("State: playtime, battery %s" % str(round(robot.battery_voltage, 2)))
time.sleep(5)
#State 4: not on charger, low battery
if (robot.battery_voltage <= 3.65) and (robot.is_on_charger == 0):
if freeplay==1:
robot.abort_all_actions(log_abort_messages=False)
robot.wait_for_all_actions_completed()
robot.stop_freeplay_behaviors()
robot.enable_all_reaction_triggers(False)
robot.world.disconnect_from_cubes()
freeplay=0
robot.play_anim_trigger(cozmo.anim.Triggers.NeedsMildLowEnergyRequest, ignore_body_track=True).wait_for_completed()
robot.set_all_backpack_lights(cozmo.lights.blue_light)
robot.set_head_angle(degrees(0)).wait_for_completed()
robot.move_lift(-3)
robot.drive_straight(distance_mm(-30), speed_mmps(50)).wait_for_completed()
os.system('cls' if os.name == 'nt' else 'clear')
print("State: finding charger, battery %s" % str(round(robot.battery_voltage, 2)))
# charger location search
charger = None
# see if we already know where the charger is
if robot.world.charger:
if robot.world.charger.pose.origin_id == robot.pose.origin_id:
#we know where the charger is
os.system('cls' if os.name == 'nt' else 'clear')
print("State: 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()
charger = robot.world.charger
print (charger)
else:
# we know where the charger is but we have been delocalized
os.system('cls' if os.name == 'nt' else 'clear')
print("State: robot delocalized recently, battery %s" % str(round(robot.battery_voltage, 2)))
pass
# 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: looking 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()
look_around = robot.start_behavior(cozmo.behavior.BehaviorTypes.LookAroundInPlace)
try:
charger = robot.world.wait_for_observed_charger(timeout=30)
os.system('cls' if os.name == 'nt' else 'clear')
print("State: found charger, battery %s" % str(round(robot.battery_voltage, 2)))
except asyncio.TimeoutError:
os.system('cls' if os.name == 'nt' else 'clear')
print("State: unable to find charger, battery %s" % str(round(robot.battery_voltage, 2)))
robot.play_anim_trigger(cozmo.anim.Triggers.CodeLabUnhappy, ignore_body_track=True).wait_for_completed()
robot.set_head_angle(degrees(0)).wait_for_completed()
finally:
# stop the behavior
look_around.stop()
# Charger location and docking handling here
if charger:
while (robot.is_on_charger == 0):
robot.set_lift_height(0.8,0.8,0.8,0.1).wait_for_completed()
# Yes! Attempt to drive near to the charger, and then stop.
os.system('cls' if os.name == 'nt' else 'clear')
print("State: moving to charger, battery %s" % str(round(robot.battery_voltage, 2)))
robot.play_anim_trigger(cozmo.anim.Triggers.CodeLabChatty, ignore_body_track=True, ignore_head_track=True).wait_for_completed()
robot.move_lift(-3)
robot.set_head_angle(degrees(0)).wait_for_completed()
action = robot.go_to_pose(charger.pose)
action.wait_for_completed()
robot.drive_straight(distance_mm(-20), speed_mmps(50)).wait_for_completed()
# we should be right in front of the charger, can we see it?
if (charger.is_visible==False):
#No we can't see it. Remove charger from navigation map and quit this loop.
robot.world.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()
print("State: charger not found, clearing map. battery %s" % str(round(robot.battery_voltage, 2)))
break
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()
os.system('cls' if os.name == 'nt' else 'clear')
# Dock. Turn around and drive backwards
print("State: docking, battery %s" % str(round(robot.battery_voltage, 2)))
robot.turn_in_place(degrees(95)).wait_for_completed()
robot.turn_in_place(degrees(95)).wait_for_completed()
time.sleep( 1 )
robot.play_anim_trigger(cozmo.anim.Triggers.CubePounceFake, ignore_body_track=True).wait_for_completed()
robot.set_head_angle(degrees(0)).wait_for_completed()
robot.drive_straight(distance_mm(-145), speed_mmps(150)).wait_for_completed()
time.sleep( 1 )
# 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()
os.system('cls' if os.name == 'nt' else 'clear')
print("State: 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.play_anim("anim_gotosleep_sleeping_01").wait_for_completed()
# No, we missed. Back off and try again
else:
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.world.charger = None
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()
os.system('cls' if os.name == 'nt' else 'clear')
print("State: backing off to attempt docking, battery %s" % str(round(robot.battery_voltage, 2)))
robot.drive_straight(distance_mm(50), speed_mmps(90)).wait_for_completed()
robot.turn_in_place(degrees(-2)).wait_for_completed()
robot.drive_straight(distance_mm(150), speed_mmps(90)).wait_for_completed()
robot.turn_in_place(degrees(95)).wait_for_completed()
robot.turn_in_place(degrees(96)).wait_for_completed()
robot.set_head_angle(degrees(0)).wait_for_completed()
time.sleep( 1 )
else:
# we have not managed to find the charger. Falling back to freeplay.
robot.world.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.world.connect_to_cubes()
os.system('cls' if os.name == 'nt' else 'clear')
print("State: charger not found, falling back to 90 secs freeplay, battery %s" % str(round(robot.battery_voltage, 2)))
robot.enable_all_reaction_triggers(True)
robot.start_freeplay_behaviors()
freeplay=1
time.sleep( 90 )
#after 90 seconds end freeplay
robot.enable_all_reaction_triggers(False)
robot.stop_freeplay_behaviors()
freeplay=0
robot.world.disconnect_from_cubes()
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 )
# scheduler
#def scheduler:
# day_of_week = datetime.date.today().weekday() # 0 is Monday, 6 is Sunday
# time = datetime.datetime.now().time()
# #weekend
# if day_of_week >= 5 and (time > datetime.time(7,30) and time < datetime.time(23)):
# do_something()
#weekday mornings
# if day_of_week < 5 and (time > datetime.time(7,30) and time < datetime.time(8)):
# do_something()
#weekday evenings
# if day_of_week < 5 and (time > datetime.time(7,30) and time < datetime.time(8)):
# do_something()
cozmo.robot.Robot.drive_off_charger_on_connect = False
#cozmo.run_program(cozmo_unleashed, use_viewer=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)
# which will give you remote control over Cozmo via WASD+QERF while the 3d window has focus
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment