a
    jɀj-                     @   sd  d Z ddlZddlZddlZddlZddlZddlmZ ddlZ	ddl
mZ ddlmZ ddlmZ eejjZejZddd	d
dddddddddddddddddddddddddddddddddddddddddddddd dd!dddd"d#dd$dgd%d&d'd(d)ddddd*dgd%d+Zd6d-d.Zd7d1d2Zd3d4 Zed5kr`e  dS )8a  Courses: learn one thing at a time, in order.

A course is a sequence of stages. Each stage trains a single incentive, then
sits an exam. Pass and the next stage inherits the weights; fail and the course
stops there rather than piling a harder skill on a broken one. You cannot learn
to run before you can walk, and this is the thing that enforces it.

Two properties make the hand-over work:

  * Every incentive publishes the same fixed-width goal channels (see
    tasks.GOAL_CHANNELS), so the network shape never changes between stages.
  * A stage resumes from the previous stage's checkpoint, so stage 2 starts
    from a robot that can already stand rather than from noise.

  python course.py --course standard --run myrobot
  python course.py --list
    N)Path)RobotEnv)Policy)recordzLearn to balance, then to movez}The natural order for a wheeled biped. Stand before you drive, drive before you turn on the spot, and only then go somewhere.balancei@B 皙?   g      ?)survive_fracepisodes	pass_ratez^Legs locked straight. Just roll the wheels to stay under the body: two numbers instead of six.)taskstepsgatewhybobi gffffff?zQNow change height while staying up, so the legs and the wheels have to cooperate.recoverzESurvive a shove: recovery beyond what a gentle correction can manage.drivei 	= z5It can hold itself up, so now ask it to go somewhere.spinz>Turning on the spot is a harder balance than driving straight.gotog333333?g?)r	   r
   r   success_ratez2Combine driving and turning into reaching a place.climbg      ?g333333?z3Last, because it needs every earlier skill at once.)labeldescriptionstageszJust learn to stand upz7One stage. The quickest way to see the whole loop work.standi- zBalance is the whole job here.)standardZbalance_onlyX  c                 C   sx  t | }|p|jd}|jdd}g g d  }}	}
t|D ]}t||| ||d}|j|j }
tj	
|| }| }t|jD ]H}|j|d |dd\}}}|t|d d	d
\}}}}}|r qq||j |	t|j| q@t|}|
| }|t|
dtt| dttt|dtt| dttt||kdttt|	dt|ddS )z>Sit the exam: run N randomised episodes and measure behaviour.specZ
obs_layoutunionN)seedr   layoutT)Zdeterministicr            )r
   	episode_smean_upright_sZmedian_upright_sZworst_upright_sr   r   Zthreshold_s)r   loadmetagetranger   Z	max_steps
control_dtnprandomZdefault_rngresetactstepclipappendtboolZtask_objsuccessarrayroundfloatmeanmedianmin)Zpolicy_pathr   r
   r	   r   	spec_pathpolicyr    ZsurvivedZwinsfullZepenvrngobs_arfelltruncinfoZsurvZneed rH   */home/ghrups/robot-bench/trainer/course.pyexamineV   s6    
"
rJ         ?  c	                    s<  t |  }	td | }
|
jddd |
d d  rdztt W n ttfyb   d Y n0  du r| |	d ||t		 g ddd	 |	d
 D ]J} d
 
|d t|d | |d |d ddd| d|d  d qd d<  fdd}|  |}tt d
 }|dur|d }|g}t|	d
 | d |  d
 | d< td  d
 | d  d }|du r| r d
 | ddv r|}nJ|dkr d
 |d  }td |d  d }|d dkr| r|}|D ]} d
 | }| d< d|d< t		 |d< |  |d }td | }tdd|d d t|d d!|d"|d#t|d$t|d%d&d't|g}|r|d(t|g7 }td)|d  d*t d
  d+|d  d,|d d- d.d/|rd0nd1 
dd2 td3|d  dd2 t|j| d4 d5<}|jddd tj|tttj|tjd6}W d   n1 sB0    Y  |dkrd7|d< d7 d< |  td8| d9| d4    S |d }d:| d;|d<< d=|d< |  |d }tt||d |d>d?|d@dA|dB}||dC< |dD |dDdAk}dE|v r|o|dE |dE k}|r(dndF|d< t		 |dG< |  tdH|dI  dJ|dK  dL|dD dM dNdO|dDdAdM dNdP|d   
dd2 |s|du rdQndR d< |  tdS|d  d,|d  dT    S |}q|durdR d< t|t d
 d  d< ndU d< t d
  d< |  tdV  S )Wa'  Run every stage, or just one.

    `only` (1-based) runs a single stage and seeds it from the previous stage's
    best policy if that stage has been passed. That is what lets the bench work
    one step at a time under the user's control instead of running the whole
    course unattended.
    runsT)parentsexist_okzcourse.jsonNr   runningr   )courser   runr   startedr   statuscurrentr   r   r   r   r   pending__)r   r   r   r   rT   examr=   rR   rT   c                     s>   t d } tj | dd W d    n1 s00    Y  d S )Nwr"   )indent)openjsondump)fstateZ
state_pathrH   rI   save   s    zrun_course.<locals>.saver"   rR   zpolicy_latest.json)stoppedfailedzpolicy_best.jsonpassedrU   trainingrS   ztrain.pyz--taskz--steps--run--spec--envs	--workersz--layoutr   --snapshot-everyz--resumez
=== stage /: z (    .Az.1fzM steps)z
  resuming )flushz    z.outrY   )cwdstdoutstderrerrorz    stage failed (exit z); see runs/z../runs/z/policy_best.jsonr=   	examiningr
   r   r	   r   )r
   r	   r<   rX   r   r   rc   finishedz    exam: upright r&   zs of r%   zs, pass rate d   z.0fz	% (needs z%)  -> rb   idlez
Stage z4) did not pass. Give it more steps and run it again.completez
Done.)COURSESROOTmkdirexistsr\   r'   r[   OSError
ValueErrortimer2   intr*   lenr)   PYstrprintparent
subprocesscallr   __file__STDOUTrJ   upperr;   )Zcourse_nameZrun_namer   envsworkerssteps_scalesnapshot_everyresume_fromonlyrQ   run_dirstra   ZcarrytodoidxZ
own_latestprevZ	prev_bestiZ	stage_runZ	stage_dirargvlogrcbestgrX   rd   rH   r_   rI   
run_coursey   s    	






&&



r   c                  C   s  t  } | jddd | jdd d | jdttd d | jdtdd	 | jd
tdd	 | jdtddd | jdtdd	 | jdd dd | jdtd dd | jddd |  }|jrJt	
 D ]\}}td| d|d   td|d   t|d d D ]>\}}td| d!|d" d#d$|d% d& d'd(|d)   qqd S |jphd*|j d+td, }t|j|tt|j |j|j|j|j|j|j	 d S )-Nz--courser   )defaultrf   rg   zrobots/wheeled_biped.jsonrh      )typer   ri   r$   z--steps-scalerK   z6scale every stage's budget, e.g. 0.1 for a quick trial)r   r   helprj   rL   z--resume-fromzcheckpoint to seed stage 1 from)r   r   z--onlyz;run just this stage (1-based), seeded from the previous onez--list
store_true)action
rl   r   z  r   r   r"   z. r   Z8s r   rm   z4.1fzM  r   course_rB   z%Y%m%d_%H%M%S)argparseArgumentParseradd_argumentr   rz   r   r8   
parse_argslistry   itemsr   	enumeraterR   rQ   r   strftimer   r   r   resolver   r   r   r   r   r   )Zapargsnamecr   srR   rH   rH   rI   main   s<    

: r   __main__)r   r   r   N)rK   rL   NN)__doc__r   r\   r   sysr   pathlibr   numpyr,   r?   r   Zppor   rolloutr   r   r   rz   
executabler   ry   rJ   r   r   __name__rH   rH   rH   rI   <module>   s   




#
/  
#  
 
