a
    nɀjpT                  	   @   s
  d Z ddlZddlZejd Zdd Zg dZdd eeD Z	G d	d
 d
Z
G dd de
ZG dd deZG dd de
ZG dd de
ZG dd de
ZG dd de
ZG dd de
ZG dd de
Zdd eeeeeeeefD ZddiZd#dd Zd!d" ZdS )$a  The incentive library.

A task is what the robot is being paid to do. It owns four things: any scenery
it needs, the goal information the robot is allowed to observe, the reward, and
what counts as failing.

Nothing here tells the robot how to move. Every task is expressed as a payoff.

Note on goal observations: a task like `goto` has to tell the robot where the
goal is, and that information has to come from somewhere real. Treat those
channels as a localisation source on the robot (UWB beacon, vision, or wheel
odometry with a known origin). They are listed in the UI as goal sensing so the
distinction from "free knowledge of world state" stays visible. Base tilt,
velocity and absolute pose remain reward-only.
    Ng     f@c                 C   s<   | \}}}}t d|| ||   dd|| ||    S )N      )mathatan2)qwxyz r   )/home/ghrups/robot-bench/trainer/tasks.py	_quat_yaw   s    r   )	cmd_vxcmd_wzspin_wz
spin_driftgoal_bxgoal_by
goal_range	step_dist
cmd_heightc                 C   s   i | ]\}}||qS r   r   ).0icr   r   r   
<dictcomp>(       r   c                   @   s   e Zd ZdZdZdZdZdZdZg Z	g Z
dZg ZdddZed	d
 Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zedd Zedd ZdS ) TaskbaseZBase N      (@unionc                 C   s    || _ |pi | _d| _|| _d S )N      ?)speccfg
curriculumlayoutselfr"   r#   r%   r   r   r   __init__7   s    
zTask.__init__c                 C   s   | j dkrttS t| jS )Nr    )r%   lenGOAL_CHANNELSchannelsr'   r   r   r   	obs_extra=   s    zTask.obs_extrac                 C   s   i S )z?Goal information this incentive is allowed to publish, by name.r   r'   envr   r   r   channel_valuesA   s    zTask.channel_valuesc                    s6   |  | | jdkrtn| j}t fdd|D S )Nr    c                    s   g | ]}t  |d qS )        )floatget)r   nvr   r   
<listcomp>H   r   zTask.obs.<locals>.<listcomp>)r0   r%   r*   r+   nparray)r'   r/   namesr   r5   r   obsE   s    
zTask.obsc                 C   s   d S Nr   r'   r/   rngr   r   r   resetK   s    z
Task.resetc                 C   s   d S r<   r   r=   r   r   r   on_stepN   s    zTask.on_stepc                 C   s   dS )z@World position of the current goal, or None. Drawn by the bench.Nr   r.   r   r   r   goal_markerQ   s    zTask.goal_markerc                 C   s   t d S r<   )NotImplementedError)r'   r/   actionr   r   r   rewardU   s    zTask.rewardc                 C   s   dS NFr   r.   r   r   r   
terminatedX   s    zTask.terminatedc                 C   s   dS rE   r   r.   r   r   r   success[   s    zTask.successc                 C   s   | j j| j }| j j| j }|dd tt|d  |dd tt|| j	 d  |dd tt|| j
 d  dS )Ntorquer1   r   action_ratejoint_nominal)rH   rI   rJ   )dataqposleg_joint_idsactuator_forceact_idxr3   r2   r8   sumZprev_actionZ	q_nominal)r/   rC   r   Zq_legtaur   r   r   _posture_   s    $$zTask._posturec                 C   s<   | dd| dd| j | dd | j| j d  dS )	Naliver!   upright       @height       @r   )rS   rT   rV   )r3   up_zrV   h_target)r/   r   r   r   r   _stay_upl   s    
zTask._stay_up)Nr    )__name__
__module____qualname__namelabeldescription	actuatorspose
init_noisegoal_sensingr+   	episode_spropsr(   propertyr-   r0   r;   r?   r@   rA   rD   rF   rG   staticmethodrR   rZ   r   r   r   r   r   +   s2   


r   c                   @   s@   e Zd ZdZdZdZdZddddd	d
ddZdd Zdd Z	dS )StandZstandzStand stillzHold station on the wheels without falling. Staying put is rewarded by position, not by stillness, because balancing IS constant small wheel motion.      $@r!         @rW         ?~jtX?{Gzt?333333?)rS   rT   rV   anchorrH   rI   rJ   c                 C   s   |j d d  | _d S Nr   )base_poscopyoriginr=   r   r   r   r?      s    zStand.resetc                 C   sv   t tj|jd d | j }| || j}| jd t	|d  d  |d< |
| ||| j t| |fS )Nr   rp         ?)r2   r8   linalgnormrr   rt   rZ   Wr   expupdaterR   rP   values)r'   r/   rC   drifttermsr   r   r   rD      s
     "zStand.rewardN)
r[   r\   r]   r^   r_   r`   re   rx   r?   rD   r   r   r   r   ri   u   s   ri   c                   @   sD   e Zd ZdZdZdZdZdZdZdddddZ	dddd	dd
dZ
dS )BalanceaS  Stand, but with the legs bolted at the standing pose.

    The whole problem becomes "drive the wheels forward and back to stay under
    the body" - two numbers instead of six. There is no reason to make the
    robot search leg poses before it can even stay upright, and a 2-D problem
    trains in minutes rather than half an hour.
    balancezBalance on the wheelszmLegs locked straight, so the only thing to learn is rolling the wheels back and forth to stay under the body.rj   )Z	l_wheel_aZ	r_wheel_ar1   l_hipl_kneer_hipr_kneegQ?g{Gz?)jointZbase_zZ	base_rollZ
base_pitchZbase_yawZbase_velN)r[   r\   r]   __doc__r^   r_   r`   re   ra   rb   rc   r   r   r   r   r~      s   r~   c                	       s   e Zd ZdZdZdZdZdgZdgZdZ	ddddd	Z
d
dddd
ddddZd  fdd	Zdd Zdd Zdd Zdd Zdd Zdd Z  ZS )!BobaN  Balance while deliberately changing height.

    Squatting and rising moves the centre of mass vertically, which changes the
    pendulum under the controller while it is running. Learning this after
    plain balancing, and before shoves, is the natural order: it is the first
    time the legs and the wheels have to cooperate.
    bobzBob up and downzFollow a height command while staying upright. The legs change the pendulum the wheels are balancing, so the two have to work together.zcommanded body heightr   r   r1   r   r!   rk   g      @rm   rn   )rS   rT   rV   track_hrp   rH   rI   rJ   Nr    c                    sn   t  ||| | jdd| _| jdd| _| jdd| _t| jdd| _t	
| j| j| j| _d S )	Nlowg
ףp=
?highgGz?
resample_s      @gates   )superr(   r#   r3   r   r   r   intZn_gatesr8   linspacer   r&   	__class__r   r   r(      s    zBob.__init__c                 C   s^   || _ |jd d  | _|j| _t| jtt	
t| j| j  | _| | | j| _d S rq   )r>   rr   rs   rt   rY   midr2   r   r   r8   argminabstarget_pickr   _nextr=   r   r   r   r?      s    &
z	Bob.resetc                    s   j j j }jt| |g   fddjD }|sftjtt	t
jj  g}fdd|D }tj|p|_d S )Nc                    s8   g | ]0} d  d |  kr, d d krn q|qS )r   g&.>r   r   r   g)nearr   r   r7      r   zBob._pick.<locals>.<listcomp>c                    s(   g | ] }t |t d d dkr|qS )r   ư>)r   getattrr   r,   r   r   r7      r   )r   r   r$   r   r8   r9   r   r2   r   r   r   r>   choicer   )r'   r/   spanZallowedoptionsr   )r   r'   r   r      s    &z	Bob._pickc                 C   s   t tt| j| j S r<   )r   r8   r   r   r   r   r,   r   r   r   
gate_index   s    zBob.gate_indexc                 C   s(   |j | jkr$| | |j | j | _d S r<   )tr   r   r   r=   r   r   r   r@      s    
zBob.on_stepc                 C   s   d| j | j d iS )Nr   rj   )r   r   r.   r   r   r   r0      s    zBob.channel_valuesc                 C   s   |j | j }ttj|jd d | j }| jd | jd |j	 d}| jd t
|d  d  |d< | jd t
|d  d  |d< || ||| j t| |fS )	Nr   rS   rT   )rS   rT   r   g{Gzd?rp   ru   )rV   r   r2   r8   rv   rw   rr   rt   rx   rX   r   ry   rz   rR   rP   r{   )r'   r/   rC   errr|   r}   r   r   r   rD      s     ""z
Bob.reward)Nr    )r[   r\   r]   r   r^   r_   r`   rd   r+   re   rb   rx   r(   r?   r   r   r@   r0   rD   __classcell__r   r   r   r   r      s$   r   c                
       s~   e Zd ZdZdZdZddgZddgZdZd	d
dddddddd	Z	d! fdd	Z
dd Zdd Zdd Zdd Zdd  Z  ZS )"DrivedrivezDrive to commandz~Follow a forward-speed and turn-rate command that changes every few seconds. This is the general-purpose locomotion incentive.zcommanded forward speedcommanded turn rater   r   r   r!   rU   rW   rl   333333?rm   rn   ro   皙?)	rS   rT   rV   track_vxtrack_wzrH   rI   rJ   	yaw_driftNr    c                    sL   t  ||| | j}|dddg| _|dddg| _|dd| _d S )	Nvx_rangeg333333r   wz_rangeg      r!   r         @)r   r(   r#   r3   r   r   r   )r'   r"   r#   r%   r   r   r   r   r(     s
    zDrive.__init__c                 C   s   || _ |   | j| _d S r<   )r>   	_resampler   r   r=   r   r   r   r?     s    zDrive.resetc                 C   s6   | j }t| jj| j | | jj| j | g| _d S r<   )r$   r8   r9   r>   uniformr   r   cmd)r'   sr   r   r   r     s
    zDrive._resamplec                 C   s&   |j | jkr"|   |j | j | _d S r<   )r   r   r   r   r=   r   r   r   r@     s    zDrive.on_stepc                 C   s   | j d | j d dS )Nr   r   )r   r   )r   r.   r   r   r   r0   #  s    zDrive.channel_valuesc                 C   s   |j |j }}| || j}| jd t|d | jd  d  d  |d< | jd t|d | jd  d  d  |d< | jd  t|d d  |d< || 	||| j t
| |fS )Nr   r   r   ru   r   r   r   )	vel_local	gyro_truerZ   rx   r   ry   r   r2   rz   rR   rP   r{   )r'   r/   rC   r6   r   r}   r   r   r   rD   &  s    00 zDrive.reward)Nr    )r[   r\   r]   r^   r_   r`   rd   r+   re   rx   r(   r?   r   r@   r0   rD   r   r   r   r   r   r      s    r   c                	   @   sZ   e Zd ZdZdZdZddgZddgZdZd	d
dddddddZ	dd Z
dd Zdd ZdS )SpinspinzSpin on the spotzTurn at a commanded rate while holding position. Rewards yaw rate and punishes translation, so it has to counter-rotate the wheels rather than drive in a circle.r   zdistance from startr   r   rj   r!   rU   rW   rk   333333?rm   rn   ro   )rS   rT   rV   r   rp   rH   rI   rJ   c                 C   sp   || _ | jdddg\}}|dt|| j }|| dk rDdnd | _|jj	|j
d  d d	  | _d S )
Nr   g      r   r!         ?r   r   Zgt_posr   )r>   r#   r3   r   r   r$   random	target_wzrK   
sensordataZ_gtrs   rt   )r'   r/   r>   Zrng_loZrng_himagr   r   r   r?   <  s
    z
Spin.resetc                 C   s,   |j d d | j }| jttj|dS )Nr   )r   r   )rr   rt   r   r2   r8   rv   rw   )r'   r/   dr   r   r   r0   C  s    zSpin.channel_valuesc                 C   s   |j }ttj|jd d | j }| || j}| jd t	
|d | j d  d  |d< | jd t	
|d  d  |d< || ||| j t| |fS )Nr   r   r!   rp   g
ףp=
?)r   r2   r8   rv   rw   rr   rt   rZ   rx   r   ry   r   rz   rR   rP   r{   )r'   r/   rC   r   r|   r}   r   r   r   rD   G  s     ,"zSpin.rewardN)r[   r\   r]   r^   r_   r`   rd   r+   re   rx   r?   r0   rD   r   r   r   r   r   0  s   r   c                
       s   e Zd ZdZdZdZddgZg dZdZdd	d
ddddddd	Z	d$ fdd	Z
dd Zdd Zdd Zdd Zdd Zd d! Zd"d# Z  ZS )%GoToZgotozGo to a pointzDrive to marker A, then marker B, then A again. Rewards closing the distance, with a bonus for arriving. Nothing says how to get there.zbearing to goal (sin, cos)zrange to goalr   r   r   g      4@r!   rl   rW   r   g      D@g?rm   rn   ro   )	rS   rT   rV   progressarriveheadingrH   rI   rJ   Nr    c                    s4   t  ||| | jdd| _| jdd| _d S )Nradius皙?	tolerancer   )r   r(   r#   r3   r   r   r&   r   r   r   r(   ^  s    zGoTo.__init__c              	   C   s   || _ | jdd| j   }|ddtj }t|t| |t	| gt|t|tj  |t	|tj  gg| _
d| _d| _| || _d S )Ngffffff?g?r   r   )r>   r   r$   r   r   pir8   r9   cossin	waypointswp_ireached_dist	prev_dist)r'   r/   r>   rangr   r   r   r?   c  s     ,z
GoTo.resetc                 C   s   | j | jt| j   S r<   )r   r   r)   r,   r   r   r   _goalo  s    z
GoTo._goalc                 C   s"   t tj|  |jd d  S rq   )r2   r8   rv   rw   r   rr   r.   r   r   r   r   r  s    z
GoTo._distc                 C   s"   |   }t|d t|d dgS )Nr   r   r1   )r   r2   )r'   r/   r   r   r   r   rA   u  s    zGoTo.goal_markerc                 C   s   |   |jd d  }t|j}t| |d  t| |d   }t| |d  t| |d   }t||}||d  ||d  t|dd dS )Nr   r   r   r   g      @ro   r   )	r   rr   r   Z	base_quatr   r   r   hypotmin)r'   r/   r   ZyawbxbyZrng_r   r   r   r0   y  s    
((zGoTo.channel_valuesc                 C   s   |  |}| || j}| jd | j|  |d< || _| jd | |d  |d< d|d< || jk r| jd |d< |  jd7  _|  jd7  _|  || _|| 	||| j t
| |fS )Nr   r   r   r1   r   r   )r   rZ   rx   r   r0   r   r   r   rz   rR   rP   r{   )r'   r/   rC   r   r}   r   r   r   rD     s    

zGoTo.rewardc                 C   s
   | j dkS rq   )r   r.   r   r   r   rG     s    zGoTo.success)Nr    )r[   r\   r]   r^   r_   r`   rd   r+   re   rx   r(   r?   r   r   rA   r0   rD   rG   r   r   r   r   r   r   Q  s$   r   c                	       s   e Zd ZdZdZdZdgZdgZdZddd	d
dddddZ	d  fdd	Z
edd Zdd Zdd Zdd Zdd Zdd Z  ZS )!ClimbZclimbzClimb a stepzGet over a raised threshold and keep going. The step height rises with the curriculum, so it learns the easy lip before the hard one.zdistance to step edger   g      .@r!   rl   r   rj   g      I@rm   rn   r   )rS   rT   rV   r   crossrH   rI   rJ   Nr    c                    sD   t  ||| | jdd| _| jdd| _| jdd| _d S )Nstep_xg?
max_heightg
ףp=
?depthr   )r   r(   r#   r3   r   max_hr   r&   r   r   r   r(     s    zClimb.__init__c                 C   s   | j dd| j   S )Nru   g      ?)r   r$   r,   r   r   r   rV     s    zClimb.heightc                 C   sD   | j }ddd| jd d|d g| j| jd  d|d gg ddgS )	NstepZobstacleZboxr   r   r1   )gzG?g?gp=
ף?r!   )r^   kindtypesizeposrgba)rV   r   r   )r'   hr   r   r   build_props  s    zClimb.build_propsc                 C   s   d| _ t|jd | _d S )NFr   )crossedr2   rr   prev_xr=   r   r   r   r?     s    zClimb.resetc                 C   s"   dt d| jt|jd  d iS )Nr   r   r   r   )r   r   r2   rr   r.   r   r   r   r0     s    zClimb.channel_valuesc                 C   s   t |jd }| || j}| jd || j  |d< || _d|d< | jsp|| j| jd  krpd| _| jd |d< || 	||| j t
| |fS )Nr   r   r1   r   r   T)r2   rr   rZ   rx   r   r   r   r   rz   rR   rP   r{   )r'   r/   rC   r   r}   r   r   r   rD     s    zClimb.rewardc                 C   s   | j S r<   )r   r.   r   r   r   rG     s    zClimb.success)Nr    )r[   r\   r]   r^   r_   r`   rd   r+   re   rx   r(   rg   rV   r   r?   r0   rD   rG   r   r   r   r   r   r     s"   
	r   c                       sZ   e Zd ZdZdZdZdZdddddd	d
dZd fdd	Zdd Z	dd Z
dd Z  ZS )RecoverrecoverzSurvive shoveszStand while being pushed hard at random intervals. Trains the recovery reflex specifically, rather than hoping it falls out of the other incentives.r   rl   rk   rW   rm   rn   ro   )rS   rT   rV   settlerH   rI   rJ   Nr    c                    s8   t  ||| | jdd| _| jdddg| _d S )Nevery_srU   impulseg?g@)r   r(   r#   r3   r   r   r&   r   r   r   r(     s    zRecover.__init__c                 C   s   || _ | j| _d S r<   )r>   r   r   r=   r   r   r   r?     s    zRecover.resetc                 C   s   |j | jkr| j\}}||||| | j  }|ddtj }|jjd  |t	| 7  < |jjd  |t
| 7  < |j | j | _d S )Nr   r   r   )r   r   r   r   r$   r   r   rK   qvelr   r   r   )r'   r/   r>   lohir   r   r   r   r   r@     s    
zRecover.on_stepc                 C   sl   |j }| || j}| jd t|d d |d d   d  |d< || ||| j t| |fS )Nr   r   r   r   r   )	r   rZ   rx   r   ry   rz   rR   rP   r{   )r'   r/   rC   r6   r}   r   r   r   rD     s
    2zRecover.reward)Nr    )r[   r\   r]   r^   r_   r`   re   rx   r(   r?   r@   rD   r   r   r   r   r   r     s   	r   c                 C   s   i | ]}|j |qS r   )r^   r   r   r   r   r   r     r   Zbalance_and_driver   r    c                 C   sp   t |p
d|pd}|tvr4td|dtt t| di pDi |i }||pZi  t| | ||dS )Nr   r   zunknown incentive z; have tasks)r%   )ALIASESr3   REGISTRYKeyErrorsorteddictrz   )r"   r^   r#   r%   Ztask_cfgr   r   r   	make_task  s    r   c                   C   s   dd t  D S )z7Machine-readable list for the bench's incentive picker.c                 S   s\   g | ]T}|j |j|j |jt|jt|jt|j	
 t|d |jrPt|jndd	qS )r   N)	r^   r_   r`   re   rd   r+   Zreward_termsZhas_sceneryra   )r^   r_   r`   stripre   listrd   r+   r   rx   keyshasattrra   r   r   r   r   r7     s   
zcatalogue.<locals>.<listcomp>)r   r{   r   r   r   r   	catalogue  s    
r   )NNr    )r   r   numpyr8   r   ZDEGr   r*   	enumerateZ
GOAL_INDEXr   ri   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>   s&   

JM2!I6$
	