def record_single_demo (demo_name, calib_file, num_cameras, use_voice, config_num=None):
    """
    Records a single demo.
    @demo_name: name of demo.
    @calib_file: file to load calibration from. "", -- default -- means using the one in the master file
    @num_demos: number of demos to be recorded. -1 -- default -- means until user stops.
    @use_voice: use voice commands to start/stop demo if true. o/w use command line.   
    """
    global cmd_checker, camera_types, demo_type_dir, master_file, topic_writer

    rospy.init_node("time_to_record")
    sleeper = rospy.Rate(10)
    
    load_parameters(num_cameras)

    # Load calibration
    cpipe.initialize_calibration(args.num_cameras)
    calib_file_path = osp.join(calib_files_dir, calib_file);
    if osp.isfile(calib_file_path):
        cpipe.tfm_pub.load_calibration(calib_file_path)
    else:
        cpipe.run_calibration_sequence()

    # Get voice command and subscriber launched and ready
    greenprint(voice_cmd)
    voice_handle = subprocess.Popen(voice_cmd, stdout=devnull, stderr=devnull, shell=True)
    started_voice = True
    cmd_checker = voice_alerts()

    init_config = load_init_config(config_num)
    if init_config is None:
        greenprint("No init config. Provide random init config.")
        subprocess.call("espeak -v en 'Provide random init config.'", stdout=devnull, stderr=devnull, shell=True)
    else:
        display_init_config(init_config, old=False)
        for cam in camera_types:
            if camera_types[cam] == 'rgbd':
                save_image_services[cam](cam_publish_request)
        greenprint("Please place rope in proper position.")
        subprocess.call("espeak -v en 'Please place rope in position on screen.'", stdout=devnull, stderr=devnull, shell=True)

    if use_voice:
        time.sleep(1.2)        
        while True:
            """
            Wait for user to place rope.
            """
            if init_config is not None:
                display_init_config(init_config, old=True)
            status = cmd_checker.get_latest_msg()
            if  status in ["begin recording","done session"]:
                break
            sleeper.sleep()
    else:
        status = raw_input("Hit enter when ready to record demo (or q/Q to quit). ")
    
    display_init_config(points=None, old=False, clear=True)
    
    if status in ["done session", "q","Q"]:
        greenprint("Done recording for this session (already?).")
        return

    # Initialize names and record
    demo_dir = osp.join(demo_type_dir, demo_name)
    if osp.exists(demo_dir):
        yellowprint("%s exists! Removing directory for fresh recording."%demo_dir)
        shutil.rmtree(demo_dir)
    os.mkdir(demo_dir)

    # Need cam types and calib file copied before for visualize demo
    cam_type_file = osp.join(demo_dir, demo_names.camera_types_name)
    with open(cam_type_file,"w") as fh: yaml.dump(camera_types, fh)
    shutil.copyfile(calib_file_path, osp.join(demo_dir,demo_names.calib_name))

    ready_service_for_demo (demo_dir)

    greenprint("Recording %s."%demo_name)
    # Temp file to show recording
    with open(osp.join(demo_dir, demo_names.record_demo_temp),'w') as fh: fh.write('Recording...')
    save_demo = record_demo(demo_name, use_voice)

    if save_demo:
        with open(master_file, 'a') as fh: fh.write('- demo_name: %s\n'%demo_name)
        
        cam_model_file = osp.join(demo_dir, demo_names.camera_models_name)
        with open(cam_model_file,"w") as fh: yaml.dump(camera_models, fh)

        shutil.copyfile(calib_file_path, osp.join(demo_dir,demo_names.calib_name))
        
        generate_annotation(demo_type, demo_name)
        os.remove(osp.join(demo_dir, demo_names.record_demo_temp))
        
        greenprint("Saved %s."%demo_name)
    else:
        time.sleep(3)
        if osp.exists(demo_dir):
            yellowprint("Removing demo %s"%demo_name) 
            shutil.rmtree(demo_dir)
            yellowprint("Done")
            
    if started_voice:
        terminate_process_and_children(voice_handle)
        voice_handle.wait()
        yellowprint("stopped voice")
        
    stop_camera_saving()
    cpipe.done()
    topic_writer.done_session()
def record_pipeline ( calib_file, num_cameras, num_demos, use_voice, use_init=True, redo):
    """
    Either records n demos or until person says he is done.
    @calib_file: file to load calibration from. "", -- default -- means using the one in the master file
    @num_cameras: number of cameras being used.
    @num_demos: number of demos to be recorded. -1 -- default -- means until user stops.
    @use_voice: use voice commands to start/stop demo if true. o/w use command line.
    """
    global cmd_checker, camera_types, demo_type_dir, master_file, demo_num, latest_demo_file, topic_writer, num_saved

    time_sess_start = time.time()

    rospy.init_node("time_to_record")
    sleeper = rospy.Rate(10)
    
    load_parameters(num_cameras)

    # Load calibration
    cpipe.initialize_calibration(args.num_cameras)
    calib_file_path = osp.join(calib_files_dir, calib_file);
    if osp.isfile(calib_file_path):
        cpipe.tfm_pub.load_calibration(calib_file_path)
    else:
        cpipe.run_calibration_sequence()

    # Get voice command and subscriber launched and ready
    greenprint(voice_cmd)
    voice_handle = subprocess.Popen(voice_cmd, stdout=devnull, stderr=devnull, shell=True)
    started_voice = True
    cmd_checker = voice_alerts()

    # Start recording demos.
    while True:
        # Check if continuing or stopping
        print '\n\n'
        time.sleep(1.2)
        
        if use_init:
            if redo is None:
                init_config = load_init_config(demo_num-1)
            else:
                ind = demo_num-100-1
                init_config = load_init_config(redo[ind]-1)
            if init_config is None:
                greenprint("No init config. Provide random init config.")
                subprocess.call("espeak -v en 'Provide random init config.'", stdout=devnull, stderr=devnull, shell=True)
            else:
                display_init_config(init_config, old=False)
                for cam in camera_types:
                    if camera_types[cam] == 'rgbd':
                        save_image_services[cam](cam_publish_request)
                greenprint("Please place rope in proper position.")
                subprocess.call("espeak -v en 'Please place rope in position on screen.'", stdout=devnull, stderr=devnull, shell=True)
        else:
            greenprint("No init config. Provide random init config.")
            subprocess.call("espeak -v en 'Provide random init config.'", stdout=devnull, stderr=devnull, shell=True)
        
        if use_voice:
            time.sleep(1.2)
            while True:
                """
                Wait for user to place rope.
                """
                if use_init and init_config is not None:
                    display_init_config(init_config, old=True)
                status = cmd_checker.get_latest_msg()
                if  status in ["begin recording","done session"]:
                    total_rec_start = time.time()
                    break
                sleeper.sleep()
        else:
            status = raw_input("Hit enter when ready to record demo (or q/Q to quit). ")

        for cam in camera_types:
            if camera_types[cam] == 'rgbd':
                save_image_services[cam](cam_publish_request)
        display_init_config(points=None, old=False, clear=True)

        if status in ["done session", "q","Q"]:
            greenprint("Done recording for this session.")
            break

        # Initialize names and record
        demo_name = demo_names.base_name%(demo_num)
        demo_dir = osp.join(demo_type_dir, demo_name)
        if osp.exists(demo_dir):
            yellowprint("%s exists! Removing directory for fresh recording."%demo_dir)
            shutil.rmtree(demo_dir)
        os.mkdir(demo_dir)

        # Need cam types and calib file copied before for visualize demo
        cam_type_file = osp.join(demo_dir, demo_names.camera_types_name)
        with open(cam_type_file,"w") as fh: yaml.dump(camera_types, fh)
        shutil.copyfile(calib_file_path, osp.join(demo_dir,demo_names.calib_name))

        ready_service_for_demo (demo_dir)

        greenprint("Recording %s."%demo_name)
        # Temp file to show recording
        with open(osp.join(demo_dir, demo_names.record_demo_temp),'w') as fh: fh.write('Recording...')
        save_demo = record_demo(demo_name, use_voice)
        
        if save_demo:
            time.sleep(1.2)
            subprocess.call("espeak -v en 'Saving demo %i.'"%demo_num, stdout=devnull, stderr=devnull, shell=True)
            with open(master_file, 'a') as fh: fh.write('- demo_name: %s\n'%demo_name)
            
            cam_type_file = osp.join(demo_dir, demo_names.camera_types_name)
            with open(cam_type_file,"w") as fh: yaml.dump(camera_types, fh)
            cam_model_file = osp.join(demo_dir, demo_names.camera_models_name)
            with open(cam_model_file,"w") as fh: yaml.dump(camera_models, fh)
            
            with open(latest_demo_file,'w') as fh: fh.write(str(demo_num))
            demo_num += 1
            
            generate_annotation(demo_type, demo_name)
            
            if num_demos > 0:
                num_demos -= 1
                
            os.remove(osp.join(demo_dir, demo_names.record_demo_temp))

            num_saved += 1
            greenprint("Saved %s."%demo_name)
            total_rec_finish = time.time()
            greenprint("Time taken to record + overhead: %02f"%(total_rec_finish - total_rec_start))
        else:
            if osp.exists(demo_dir):
                shutil.rmtree(demo_dir)
                yellowprint("Removed %s dir."%demo_name)
        if num_demos == 0:
            greenprint("Recorded all demos for session.")
            break
        
    if started_voice:
        terminate_process_and_children(voice_handle)
        voice_handle.wait()
        yellowprint("Stopped voice.")
    
    stop_camera_saving()    
    cpipe.done() 
    topic_writer.done_session()
    
    time_sess_finish = time.time()
    greenprint("Time taken to record in this session: %02f s"%(time_sess_finish-time_sess_start))
    if num_saved > 0:
        greenprint("Average time per saved demo: %02f s"%((time_sess_finish-time_sess_start)/num_saved))