Understand how to create and play new animations on Kuri.
Animation is at the core of Kuri’s personality. It’s how she expresses intent, communicates feedback to the user, and builds up the illusion of being a living creature with her own thoughts and personality quirks.
Every time you see Kuri nod her head in response to a voice command, you’re seeing an animation called gotit at work. Let’s try to play it on demand.
First, place Kuri in animation mode with the following command:
rostopic pub /command gizmo_msgs/Command '{ name: start_animation }' -1
In animation mode, all autonomous behavior will be suspended and Kuri will not react to touch or voice input.
Then tell Kuri to play the gotit animation:
rostopic pub /command gizmo_msgs/Command '{ name: play_stored_animation_command, params: [{ k: "name", v: "gotit" }] }' -1
Kuri should nod, play a sound and her chest light should pulse green.
If you’d like to experiment with other animations, take a look at the list of built-in animations at the end of this document and substitute the name gotit in the example above with the name of the animation you want to play.
As you saw in the gotit example, Kuri’s animations have 3 basic components:
An animation is a combination of any of the 3 components. Now, let’s take a look at each one of the files that back these components.
Animation files that describe Kuri’s movement are stored in /opt/gizmo/share/assets/anims. Each file is in the .atom format, developed by Autodesk for Maya.
Note that while .atom files can include animations that move the body forwards or backwards, those movements will be ignored by the animation parser. For now, only rotation of the body is supported through animation defined in .atom files.
Kuri’s sounds are stored in /opt/gizmo/share/assets/sounds as .wav files. Each file has the following properties:
48000Hz16 bit signed (le)2Chest light animations are stored in /opt/gizmo/share/assets/movies as .mov files. Each frame of video is sampled in 15 locations - each corresponding to one of the 15 LEDs of the chest light. When building your own chest light animations, make sure the exported files have the following properties:
movh.26460fpsThe individual components are combined into a single performance through a simple JSON wrapper called an animation container. Animation containers are stored in /opt/gizmo/share/assets/anims/containers and have the following structure:
{
"animation": "test.atom",
"relative": true,
"audio": [
{
"file": "test.wav",
"time": 0.0
},
{
"file": "test2.wav",
"time": 2.2
}
],
"chest": "test.mov"
}
Here’s what the different fields in the container describe:
animation is the .atom file in assets/anims that defines body, head and eyelid movements.
relative is true or false depending on whether the movement starts with the current orientation of the head/body/eyelids considered to be (0, 0) or not. The default is false.
audio is an array of files in assets/sounds that will play with the animation and the time (in seconds) the sounds will start. You can use multiple sounds in the same animation.
chest is the video in assets/movies describing the chest light animation that will be played along with the movement and audio.
The name of the container becomes the name of the animation at runtime, so a container named gotit.json describes an animation called gotit.
Animation sets provide additional flexibility when working with animations by letting you:
Animation sets are defined in /opt/gizmo/share/gizmo/configs/animation_sets.json. Here’s what an example set looks like:
{
"test_set": {
"neutral": [
{
"default_anim": "yes",
"weight": 1.0,
"dock_variant": "yes_docked"
}
],
"happy": [
{
"default_anim": "yes_happy",
"weight": 0.8,
"dock_variant": "yes_happy_docked"
},
{
"default_anim": "no_happy",
"weight": 0.2,
"dock_variant": "no_happy_docked"
}
],
"sad": [
{
"default_anim": "yes_sad",
"weight": 1.0,
"dock_variant": "yes_sad_docked"
}
]
},
...
}
Each key: value pair in the JSON object represents a single animation set. In the example above, test_set is the name of the animation set. When the animation player is asked to play an animation with a specific name, it will check to see if a set by that name exists first. Each object representing a set has the following properties:
neutral - an array of animations to pick from when Kuri’s mood is neutral, or when no happy or sad set is defined. This is the only required property in an animation set.happy - an array of animations to pick from when Kuri’s mood is happy.sad - an array of animations to pick from when Kuri’s mood is sad.Each animation in the arrays above has the following properties:
default_anim - the name of the animation that should be played. This can be the name of an animation container, or the name of one of the built-in animations. Built-in animations take precedence.weight - the weight to use when randomly picking an animation from the list. In the example above, there’s an 80% chance that yes_happy will be picked when Kuri is happy. Default is 1.docked_variant - the name of the animation that should be played when Kuri is on the dock. If omitted, the default_anim will be played, instead.You will need:
kuri-bridge if you’d like to preview your animations on the robot as you’re working on themFollow the installation instructions in the plug-in package to enable the Kuri Animator menu in Maya’s menu bar. Once that’s done, start Kuri Bridge and connect to your robot. Kuri Bridge will enable animations that you’re working on in Maya to play directly on the robot. The Maya plug-in uses the bridge by default, so there’s no further configuration you need to do.
Open the Kuri_v1.ma template included in the plug-in package. You should see a 3D model of Kuri and controls for the different joints that can be animated (the eyelid and head controls are to Kuri’s right, while the body controls are around the base of the robot).

If you want to test out your animation at any point, open the Kuri Animator menu and select Play Animation.
Once you’re done with your animation, select Kuri Animator > Export animation to file. This will save a .atom file with the animation you just created.
Copy the resulting .atom file to /opt/gizmo/share/assets/anims.
You will need:
Open the KuriChestLightRig.aep template. It looks like this:

The template includes a few different presets for chest light animations, such as a pulse, and a starburst, but you can create your own by animating each of the individual LED layers in the rig.
Once your animation is ready, export it as a .mov file (in AE’s export settings, choose QuickTime as format). Since the latest version of AE doesn’t export to h.264 by default, the resulting file will be quite large. It’s recommended that you transcode it to h.264 to reduce the file size.
Copy the resulting .mov file to /opt/gizmo/share/assets/movies.
There are a few different ways to do this:
Export animation container option in the Maya plug-in. When prompted for the name of the animation file, enter in only the name, not the path to the file.kuri-bridgeCopy the .json container file to /opt/gizmo/share/assets/anims/containers. Then, restart gizmo:
sudo service gizmo restart
If you replaced one of the built-in animations, you will also need to clear the asset cache:
sudo rm -rf /tmp/cache
sudo service gizmo restart
Then, play your animation:
rostopic pub /command gizmo_msgs/Command '{ name: start_animation }' -1
rostopic pub /command gizmo_msgs/Command '{ name: play_stored_animation_command, params: [{ k: "name", v: "name_of_your_animation" }] }' -1
You can wire up your new animation to various triggers using the rules engine (see managing-rules).
Programmatic animations are written in Python and are part of Kuri’s codebase. They can’t be modified, and will take precedence over an animation from an animation container with the same name.
at_attention_look_aroundat_attention_resetattention_look_around_3battery_criticalbattery_lowblinkboot_upbumpcapture_startcritical_batterydance_donedance_music_detecteddocking_back_indocking_back_updocking_complete_asleepdocking_complete_awakedocking_complete_happydocking_looking_for_dockdocking_preparing_to_approachdocking_resetdocking_turn_ccwdocking_turn_cwdocking_waypoint_reacheddouble_blinkface_detectedface_lostfartgotit_dockedgreeting_face_no_soundgreeting_face_soundgreeting_first_capturehappy_birthdayhead_touch_endhead_touchhuh1_dockedhuh1_offline_dockedhuh1_offlinehuh1huh2i_love_youlistening_poselisteninglive_undocklook_around_adultslook_around_kids_petslostlullaby_songnight_lightnoobserver_endobserver_indicatorobserver_startold_gigglepickupputdownredockrepositionreset_headreset_sadsadscripted_idlesearch_first_capturesearch_user_captureseizuresheepsmilestart_soundstoptap_head_find_facetest_eyestest_pantest_tilttickle_endtickletriple_blinktwitch_1twitch_2twitch_3twitch_4undock_and_scanundock_from_old_homeundockwakeup_autowakeup_fastwaypoint_reachedyesAnimations from animation containers live under the /opt/gizmo/share/assets directory. The files are editable and can be easily inspected.
alarm1alarm1_dockedalarm2alarm2_dockedalarm3alarm3_dockedattention_look_around_2bang_bang_reboot_boredbang_bang_reboot_chucklebang_bang_reboot_dockedbang_bang_reboot_dramaticbark_doublebark_singlebluetooth_connectedbluetooth_pairingbluetooth_pairing_dockedboredom_30sboredom_45sboredom_45s_dockedboredom_60sboredom_60s_dockedboredom_pancake_hum_longboredom_pancake_hum_shortboredom_sneeze_longboredom_sneeze_normalboredom_sneeze_shortboredom_sneeze_to_sideboredom_yawnbye_1bye_2capturingcapturing_liveexamplegiggle_2giggle_2_dockedgiggle_3giggle_3_dockedgiggle_4giggle_4_dockedgiggle_5giggle_5_dockedgiggle_6giggle_6_dockedgood_nightgreeting_1greeting_2happy_new_yearhead_tap_unboxing_1head_tap_unboxing_2head_tap_unboxing_3head_tap_unboxing_4i_love_you_dockedjoke_1joke_1_dockedjoke_2joke_3live_fartlive_frownlive_kisslive_lovelive_love_dockedlive_nolive_smilelive_yeslost_normallost_sighlove_relative_1love_relative_2meow_1meow_2moment_capturemoment_capture_livenew_homenew_spot_1new_spot_2no_1no_2no_3no_point_to_chestlightnuzzle_into_hand_1nuzzle_into_hand_1_dockednuzzle_into_hand_2onboarding_backward_1onboarding_backward_2onboarding_backward_release_1onboarding_forwardonboarding_nodriving_1onboarding_saving_map_1onboarding_saving_map_2onboarding_saving_map_3onboarding_saving_map_4onboarding_turn_left_1onboarding_turn_left_2onboarding_turn_releaseonboarding_turn_right_1onboarding_turn_right_2overloadpancake_humphoto_shoot_1photo_shoot_1_dockedphoto_shoot_2photo_shoot_3photo_shoot_3_dockedponder_happyponder_neutralponder_sadproud_1proud_2sleep_fighting_itsleep_quicksleep_slowsleep_very_quicksneeze_longsneeze_normalsneeze_shortsneeze_to_sidestartlethank_you_1thank_you_2wolf_whistleyes_1yes_2yes_3yes_critical_battery