def create_put_down_in_slot_type_constraint(sim, target, slot_types_and_costs):
    constraints = []
    for (slot_type, cost) in slot_types_and_costs:
        if cost is None:
            pass
        slot_manifest_entry = SlotManifestEntry(target,
                                                PostureSpecVariable.ANYTHING,
                                                slot_type)
        slot_manifest = SlotManifest((slot_manifest_entry, ))
        posture_state_spec_stand = PostureStateSpec(
            STAND_POSTURE_MANIFEST, slot_manifest,
            PostureSpecVariable.ANYTHING)
        posture_constraint_stand = Constraint(
            debug_name='PutDownInSlotTypeConstraint_Stand',
            posture_state_spec=posture_state_spec_stand,
            cost=cost)
        constraints.append(posture_constraint_stand)
        posture_state_spec_sit = PostureStateSpec(SIT_POSTURE_MANIFEST,
                                                  slot_manifest,
                                                  PostureSpecVariable.ANYTHING)
        posture_constraint_sit = Constraint(
            debug_name='PutDownInSlotTypeConstraint_Sit',
            posture_state_spec=posture_state_spec_sit,
            cost=cost)
        constraints.append(posture_constraint_sit)
    if not constraints:
        return Nowhere()
    final_constraint = create_constraint_set(constraints)
    return final_constraint
 def get_access_constraint(self, put, inventory_owner):
     entries = []
     entries.append(PostureManifestEntry(None, MATCH_ANY, MATCH_ANY, MATCH_ANY, MATCH_ANY, MATCH_ANY, inventory_owner))
     surface_posture_manifest = PostureManifest(entries)
     surface_posture_state_spec = PostureStateSpec(surface_posture_manifest, SlotManifest().intern(), PostureSpecVariable.ANYTHING)
     constraint_total = interactions.constraints.Constraint(debug_name='Required Surface For Generic Get Put', posture_state_spec=surface_posture_state_spec)
     for constraint_factory in self.constraints:
         constraint = constraint_factory.create_constraint(None, target=inventory_owner)
         constraint_total = constraint_total.intersect(constraint)
     return constraint_total
예제 #3
0
 def _create_drive_posture_constraint(self, posture_type):
     posture_manifest = PostureManifest()
     entry = PostureManifestEntry(AnimationParticipant.ACTOR,
                                  posture_type.name,
                                  posture_type.family_name, MATCH_ANY,
                                  MATCH_NONE, MATCH_NONE, MATCH_ANY, None)
     posture_manifest.add(entry)
     posture_manifest = posture_manifest.intern()
     posture_state_spec = PostureStateSpec(posture_manifest, SlotManifest(),
                                           PostureSpecVariable.ANYTHING)
     return Constraint(posture_state_spec=posture_state_spec,
                       debug_name='VehiclePostureConstraint')
예제 #4
0
class GoHereSuperInteraction(TerrainSuperInteraction):
    __qualname__ = 'GoHereSuperInteraction'
    POSTURE_MANIFEST = PostureManifest(
        (PostureManifestEntry(None, 'stand', '', 'FullBody', MATCH_ANY,
                              MATCH_ANY, MATCH_NONE), )).intern()
    POSTURE_STATE_SPEC = PostureStateSpec(POSTURE_MANIFEST,
                                          SlotManifest().intern(), None)
    CONSTRAINT = Constraint(debug_name='GoHere',
                            posture_state_spec=POSTURE_STATE_SPEC,
                            allow_small_intersections=True)
    _ignores_spawn_point_footprints = True

    @classmethod
    def _test(cls, target, context, **kwargs):
        (position, surface) = cls._get_position_and_surface(target, context)
        if position is None:
            return TestResult(False,
                              'Cannot go here without a pick or target.')
        routing_location = routing.Location(position,
                                            sims4.math.Quaternion.IDENTITY(),
                                            surface)
        if not routing.test_connectivity_permissions_for_handle(
                routing.connectivity.Handle(routing_location),
                context.sim.routing_context):
            return TestResult(False, 'Cannot GoHere! Unroutable area.')
        return TestResult.TRUE

    @classmethod
    def potential_interactions(cls, target, context, **kwargs):
        (position, surface) = cls._get_position_and_surface(target, context)
        if position is not None and context is not None and context.sim is not None:
            main_group = context.sim.get_visible_group()
            if main_group is not None and not main_group.is_solo:
                group_constraint = next(
                    iter(main_group.get_constraint(context.sim)))
                if group_constraint is not None and group_constraint.routing_surface == surface:
                    while True:
                        for constraint in group_constraint:
                            group_geometry = constraint.geometry
                            while group_geometry is not None and group_geometry.contains_point(
                                    position):
                                yield AffordanceObjectPair(cls,
                                                           target,
                                                           cls,
                                                           None,
                                                           ignore_party=True,
                                                           **kwargs)
                                return
        if cls._can_rally(context):
            for aop in cls.get_rallyable_aops_gen(target, context, **kwargs):
                yield aop
        yield cls.generate_aop(target, context, **kwargs)
예제 #5
0
def create_carry_nothing_constraint(hand, debug_name='CarryNothing'):
    entries = []
    if hand == Hand.LEFT:
        entries = (PostureManifestEntry(None, MATCH_ANY, MATCH_ANY, MATCH_ANY,
                                        MATCH_NONE, MATCH_ANY, MATCH_ANY), )
    else:
        entries = (PostureManifestEntry(None, MATCH_ANY, MATCH_ANY, MATCH_ANY,
                                        MATCH_ANY, MATCH_NONE, MATCH_ANY), )
    carry_posture_manifest = PostureManifest(entries)
    carry_posture_state_spec = PostureStateSpec(carry_posture_manifest,
                                                SlotManifest().intern(),
                                                PostureSpecVariable.ANYTHING)
    return interactions.constraints.Constraint(
        debug_name=debug_name, posture_state_spec=carry_posture_state_spec)
예제 #6
0
def create_carry_constraint(target,
                            hand=DEFAULT,
                            strict=False,
                            debug_name='CarryGeneric'):
    if strict and target is None:
        target = MATCH_NONE
    entries = []
    if hand is DEFAULT or hand == Hand.LEFT:
        entries.append(
            PostureManifestEntry(None, MATCH_ANY, MATCH_ANY, MATCH_ANY, target,
                                 MATCH_ANY, MATCH_ANY))
    if hand is DEFAULT or hand == Hand.RIGHT:
        entries.append(
            PostureManifestEntry(None, MATCH_ANY, MATCH_ANY, MATCH_ANY,
                                 MATCH_ANY, target, MATCH_ANY))
    carry_posture_manifest = PostureManifest(entries)
    carry_posture_state_spec = PostureStateSpec(carry_posture_manifest,
                                                SlotManifest().intern(),
                                                PostureSpecVariable.ANYTHING)
    return interactions.constraints.Constraint(
        debug_name=debug_name, posture_state_spec=carry_posture_state_spec)
예제 #7
0
def create_put_down_in_slot_type_constraint(sim,
                                            carry_target,
                                            slot_types_and_costs,
                                            target=None):
    constraints = []
    for (slot_type, cost) in slot_types_and_costs:
        if cost is None:
            continue
        if target is not None and target is not carry_target:
            slot_manifest_entry = SlotManifestEntry(
                carry_target, PostureSpecVariable.INTERACTION_TARGET,
                slot_type)
        else:
            slot_manifest_entry = SlotManifestEntry(
                carry_target, PostureSpecVariable.ANYTHING, slot_type)
        slot_manifest = SlotManifest((slot_manifest_entry, ))
        posture_state_spec_stand = PostureStateSpec(
            STAND_POSTURE_MANIFEST, slot_manifest,
            PostureSpecVariable.ANYTHING)
        posture_constraint_stand = Constraint(
            debug_name='PutDownInSlotTypeConstraint_Stand',
            posture_state_spec=posture_state_spec_stand,
            cost=cost)
        constraints.append(posture_constraint_stand)
        posture_state_spec_sit = PostureStateSpec(SIT_POSTURE_MANIFEST,
                                                  slot_manifest,
                                                  PostureSpecVariable.ANYTHING)
        posture_constraint_sit = Constraint(
            debug_name='PutDownInSlotTypeConstraint_Sit',
            posture_state_spec=posture_state_spec_sit,
            cost=cost)
        constraints.append(posture_constraint_sit)
    if not constraints:
        return Nowhere(
            'Carry Target has no slot types or costs tuned for put down: {} Sim:{}',
            carry_target, sim)
    final_constraint = create_constraint_set(constraints)
    return final_constraint
예제 #8
0
from animation.posture_manifest import PostureManifest, PostureManifestEntry, AnimationParticipant, MATCH_ANY, SlotManifest
from interactions.base.basic import TunableBasicContentSet
from interactions.base.super_interaction import SuperInteraction
from interactions.constraints import Constraint
from event_testing.results import TestResult
from postures.posture_state_spec import PostureStateSpec
from sims4.tuning.tunable import TunableReference
import services
CARRY_TARGET_POSTURE_MANIFEST = PostureManifest((PostureManifestEntry(None, None, None, None, AnimationParticipant.TARGET, MATCH_ANY, MATCH_ANY), PostureManifestEntry(None, None, None, None, MATCH_ANY, AnimationParticipant.TARGET, MATCH_ANY))).intern()
CARRY_TARGET_POSTURE_STATE_SPEC = PostureStateSpec(CARRY_TARGET_POSTURE_MANIFEST, SlotManifest().intern(), None)

class PickUpObjectSuperInteraction(SuperInteraction):
    __qualname__ = 'PickUpObjectSuperInteraction'
    INSTANCE_TUNABLES = {'basic_content': TunableBasicContentSet(one_shot=True, no_content=True, default='no_content'), 'si_to_push': TunableReference(services.affordance_manager(), description='SI to push after picking up the object.')}

    @classmethod
    def _constraint_gen(cls, *args, **kwargs):
        yield Constraint(debug_name='PickUpObjectSuperInteraction({})'.format(cls.si_to_push), posture_state_spec=CARRY_TARGET_POSTURE_STATE_SPEC)

    @classmethod
    def _test(cls, target, context, **kwargs):
        from sims.sim import Sim
        if isinstance(target.parent, Sim):
            return TestResult(False, 'Cannot pick up an object parented to a Sim.')
        if context.source == context.SOURCE_AUTONOMY and context.sim.posture_state.get_carry_track(target.definition.id) is not None:
            return TestResult(False, 'Sims should not autonomously pick up more than one object.')
        return TestResult.TRUE

class CarryCancelInteraction(SuperInteraction):
    __qualname__ = 'CarryCancelInteraction'
예제 #9
0
    def __init__(self,
                 sim,
                 current_posture_state,
                 posture_spec,
                 var_map,
                 invalid_expected=False,
                 body_state_spec_only=False,
                 carry_posture_overrides=frozendict(),
                 is_throwaway=False):
        def _get_default_carry_aspect(track):
            if track in carry_posture_overrides:
                return carry_posture_overrides[track]
            return postures.create_posture(
                CarryPostureStaticTuning.POSTURE_CARRY_NOTHING,
                sim,
                None,
                track=track)

        self._constraint_intersection = None
        self._constraint_intersection_dirty = True
        self._spec = posture_spec
        self._sim_ref = sim.ref()
        self._linked_posture_state = None
        self._valid = True
        self._constraints = {}
        self._invalid_expected = invalid_expected
        self.body_state_spec_only = body_state_spec_only
        self._posture_constraint = None
        self._posture_constraint_strict = None
        body_index = BODY_INDEX
        body_posture_type_index = BODY_POSTURE_TYPE_INDEX
        body_target_index = BODY_TARGET_INDEX
        spec_body = posture_spec[body_index]
        self.body_target = spec_body[body_target_index]
        if current_posture_state is None or spec_body[
                body_posture_type_index] != current_posture_state.body.posture_type or spec_body[
                    body_target_index] != current_posture_state.body.target:
            animation_context = None
            if current_posture_state is not None:
                if not current_posture_state.body.mobile:
                    if not spec_body[body_posture_type_index].mobile:
                        animation_context = current_posture_state.body.animation_context
            self._aspect_body = postures.create_posture(
                spec_body[body_posture_type_index],
                self.sim,
                self.body_target,
                animation_context=animation_context,
                is_throwaway=is_throwaway)
        else:
            self._aspect_body = current_posture_state.body
        posture_manifest = self._aspect_body.get_provided_postures(
            surface_target=self.surface_target, concrete=True)
        posture_manifest = posture_manifest.get_constraint_version(self.sim)
        posture_state_spec = PostureStateSpec(
            posture_manifest, SlotManifest(), self._aspect_body.target
            or PostureSpecVariable.ANYTHING)
        self.body_posture_state_constraint = Constraint(
            debug_name='PostureStateManifestConstraint',
            posture_state_spec=posture_state_spec)
        if body_state_spec_only:
            self._constraints[None] = self.body_posture_state_constraint
            return
        body_slot_constraint = self._aspect_body.slot_constraint
        if not (body_slot_constraint is not None and
                (self._aspect_body.is_vehicle and current_posture_state
                 is not None) and current_posture_state.body.is_vehicle):
            body_posture_constraint = self.body_posture_state_constraint.intersect(
                body_slot_constraint)
        else:
            body_posture_constraint = self.body_posture_state_constraint
        self._constraints[None] = body_posture_constraint
        if current_posture_state is not None:
            curr_spec_carry_target = current_posture_state.get_posture_spec(
                var_map)[CARRY_INDEX][CARRY_TARGET_INDEX]
        spec_carry = posture_spec[CARRY_INDEX]
        spec_carry_target = spec_carry[CARRY_TARGET_INDEX]
        if current_posture_state is not None and spec_carry_target != curr_spec_carry_target:
            if spec_carry_target is None:
                current_carry_target = var_map.get(curr_spec_carry_target)
                current_carry_track = current_posture_state.get_carry_track(
                    current_carry_target)
                if current_carry_track == PostureTrack.RIGHT:
                    self._aspect_carry_right = _get_default_carry_aspect(
                        PostureTrack.RIGHT)
                    self._aspect_carry_left = current_posture_state.left
                else:
                    self._aspect_carry_left = _get_default_carry_aspect(
                        PostureTrack.LEFT)
                    self._aspect_carry_right = current_posture_state.right
            else:
                spec_carry_posture_type = spec_carry[CARRY_POSTURE_TYPE_INDEX]
                if spec_carry_target not in var_map:
                    raise KeyError(
                        'spec_carry_target {} not in var_map:{}. Sim posture state {} and carry aspects {}, '
                        .format(spec_carry_target, var_map,
                                current_posture_state,
                                current_posture_state.carry_aspects))
                if spec_carry_posture_type not in var_map:
                    carry_target = var_map[spec_carry_target]
                    aop = posture_specs.get_carry_posture_aop(
                        sim, carry_target)
                    if aop is None:
                        raise RuntimeError(
                            'Sim {} failed to find carry posture aop for carry target {}.'
                            .format(sim, carry_target))
                    carry_posture_type = aop.affordance._carry_posture_type
                    if carry_posture_type is None:
                        raise KeyError
                    var_map += {
                        PostureSpecVariable.POSTURE_TYPE_CARRY_OBJECT:
                        carry_posture_type
                    }
                carry_target = var_map[spec_carry_target]
                carry_posture_type = var_map[spec_carry_posture_type]
                if spec_carry[CARRY_HAND_INDEX] in var_map:
                    hand = var_map[spec_carry[CARRY_HAND_INDEX]]
                else:
                    for hand in sim.posture_state.get_free_hands():
                        if hand in carry_target.get_allowed_hands(sim):
                            break
                    else:
                        raise RuntimeError('No allowable free hand was empty.')
                new_carry_aspect = postures.create_posture(
                    carry_posture_type,
                    self.sim,
                    carry_target,
                    track=hand_to_track(hand),
                    is_throwaway=is_throwaway)
                if hand == Hand.LEFT:
                    self._aspect_carry_left = new_carry_aspect
                    if current_posture_state is not None:
                        self._aspect_carry_right = current_posture_state.right
                    else:
                        self._aspect_carry_right = _get_default_carry_aspect(
                            PostureTrack.RIGHT)
                elif hand == Hand.RIGHT:
                    self._aspect_carry_right = new_carry_aspect
                    if current_posture_state is not None:
                        self._aspect_carry_left = current_posture_state.left
                    else:
                        self._aspect_carry_right = _get_default_carry_aspect(
                            PostureTrack.LEFT)
                else:
                    raise RuntimeError(
                        'Invalid value specified for hand: {}'.format(hand))
        elif current_posture_state is not None:
            self._aspect_carry_left = current_posture_state.left
            self._aspect_carry_right = current_posture_state.right
        elif spec_carry_target is not None:
            carry_target = var_map[spec_carry_target]
            spec_carry_posture_type = spec_carry[CARRY_POSTURE_TYPE_INDEX]
            carry_posture_type = var_map.get(spec_carry_posture_type)
            if carry_posture_type is None:
                aop = get_carry_posture_aop(sim, carry_target)
                if aop is None and invalid_expected:
                    return
                carry_posture_type = aop.affordance._carry_posture_type
            if spec_carry[CARRY_HAND_INDEX] in var_map:
                hand = var_map[spec_carry[CARRY_HAND_INDEX]]
            else:
                allowed_hands = carry_target.get_allowed_hands(sim)
                hand = allowed_hands[0]
            new_carry_aspect = postures.create_posture(
                carry_posture_type,
                self.sim,
                carry_target,
                track=hand_to_track(hand),
                is_throwaway=is_throwaway)
            if hand == Hand.LEFT:
                self._aspect_carry_left = new_carry_aspect
                self._aspect_carry_right = _get_default_carry_aspect(
                    PostureTrack.RIGHT)
            else:
                self._aspect_carry_right = new_carry_aspect
                self._aspect_carry_left = _get_default_carry_aspect(
                    PostureTrack.LEFT)
        else:
            self._aspect_carry_left = _get_default_carry_aspect(
                PostureTrack.LEFT)
            self._aspect_carry_right = _get_default_carry_aspect(
                PostureTrack.RIGHT)
예제 #10
0
from interactions.base.basic import TunableBasicContentSet
from interactions.base.super_interaction import SuperInteraction
from interactions.constraints import Constraint
from event_testing.results import TestResult
from postures.posture_state_spec import PostureStateSpec
from sims4.tuning.tunable import TunableReference
import services

CARRY_TARGET_POSTURE_MANIFEST = PostureManifest(
    (PostureManifestEntry(None, None, None, None, AnimationParticipant.TARGET,
                          MATCH_ANY, MATCH_ANY),
     PostureManifestEntry(None, None, None, None, MATCH_ANY,
                          AnimationParticipant.TARGET, MATCH_ANY))).intern()
CARRY_TARGET_POSTURE_STATE_SPEC = PostureStateSpec(
    CARRY_TARGET_POSTURE_MANIFEST,
    SlotManifest().intern(), None)


class PickUpObjectSuperInteraction(SuperInteraction):
    INSTANCE_TUNABLES = {
        'basic_content':
        TunableBasicContentSet(one_shot=True,
                               no_content=True,
                               default='no_content'),
        'si_to_push':
        TunableReference(services.affordance_manager(),
                         allow_none=True,
                         description='SI to push after picking up the object.')
    }

    @classmethod
예제 #11
0
def create_body_posture_state_spec(posture_manifest,
                                   body_target=PostureSpecVariable.ANYTHING):
    return PostureStateSpec(posture_manifest,
                            SlotManifest().intern(), body_target)
 def __init__(self, sim, current_posture_state, posture_spec, var_map, invalid_expected=False, body_state_spec_only=False):
     self._constraint_intersection = None
     self._constraint_intersection_dirty = True
     self._spec = posture_spec
     self._sim_ref = sim.ref()
     self._linked_posture_state = None
     self._valid = True
     self._constraints = {}
     self._invalid_expected = invalid_expected
     self.body_state_spec_only = body_state_spec_only
     self._posture_constraint = None
     self._posture_constraint_strict = None
     body_index = BODY_INDEX
     body_posture_type_index = BODY_POSTURE_TYPE_INDEX
     body_target_index = BODY_TARGET_INDEX
     spec_body = posture_spec[body_index]
     self.body_target = spec_body[body_target_index]
     if current_posture_state is None or spec_body[body_posture_type_index] != current_posture_state.body.posture_type or spec_body[body_target_index] != current_posture_state.body.target:
         animation_context = None
         if current_posture_state is not None and not current_posture_state.body.mobile and not spec_body[body_posture_type_index].mobile:
             animation_context = current_posture_state.body.animation_context
         self._aspect_body = postures.create_posture(spec_body[body_posture_type_index], self.sim, self.body_target, animation_context=animation_context)
     else:
         self._aspect_body = current_posture_state.body
     posture_manifest = self._aspect_body.get_provided_postures(surface_target=self.surface_target, concrete=True)
     posture_manifest = posture_manifest.get_constraint_version(self.sim)
     posture_state_spec = PostureStateSpec(posture_manifest, SlotManifest(), self._aspect_body.target or PostureSpecVariable.ANYTHING)
     self.body_posture_state_constraint = Constraint(debug_name='PostureStateManifestConstraint', posture_state_spec=posture_state_spec)
     if body_state_spec_only:
         self._constraints[self] = self.body_posture_state_constraint
         return
     body_slot_constraint = self._aspect_body.slot_constraint
     if body_slot_constraint is not None:
         body_posture_constraint = self.body_posture_state_constraint.intersect(body_slot_constraint)
     else:
         body_posture_constraint = self.body_posture_state_constraint
     self._constraints[self] = body_posture_constraint
     if current_posture_state is not None:
         curr_spec_carry_target = current_posture_state.get_posture_spec(var_map)[CARRY_INDEX][CARRY_TARGET_INDEX]
     spec_carry = posture_spec[CARRY_INDEX]
     spec_carry_target = spec_carry[CARRY_TARGET_INDEX]
     if current_posture_state is not None and spec_carry_target != curr_spec_carry_target:
         if spec_carry_target is None:
             current_carry_target = var_map.get(curr_spec_carry_target)
             current_carry_track = current_posture_state.get_carry_track(current_carry_target)
             if current_carry_track == PostureTrack.RIGHT:
                 self._aspect_carry_right = self._get_default_carry_aspect(PostureTrack.RIGHT)
                 self._aspect_carry_left = current_posture_state.left
             else:
                 self._aspect_carry_left = self._get_default_carry_aspect(PostureTrack.LEFT)
                 self._aspect_carry_right = current_posture_state.right
                 spec_carry_posture_type = spec_carry[CARRY_POSTURE_TYPE_INDEX]
                 if spec_carry_target not in var_map:
                     raise KeyError
                 if spec_carry_posture_type not in var_map:
                     aop = posture_specs.get_carry_posture_aop(sim, var_map[spec_carry_target])
                     carry_posture_type = aop.affordance._carry_posture_type
                     if carry_posture_type is None:
                         raise KeyError
                     var_map += {PostureSpecVariable.POSTURE_TYPE_CARRY_OBJECT: carry_posture_type}
                 carry_target = var_map[spec_carry_target]
                 carry_posture_type = var_map[spec_carry_posture_type]
                 if spec_carry[CARRY_HAND_INDEX] in var_map:
                     hand = var_map[spec_carry[CARRY_HAND_INDEX]]
                 else:
                     for hand in sim.posture_state.get_free_hands():
                         while hand in carry_target.allowed_hands:
                             break
                     raise RuntimeError('No allowable free hand was empty.')
                 new_carry_aspect = postures.create_posture(carry_posture_type, self.sim, carry_target, track=self.hand_to_track(hand))
                 if hand == Hand.LEFT:
                     self._aspect_carry_left = new_carry_aspect
                     if current_posture_state is not None:
                         self._aspect_carry_right = current_posture_state.right
                     else:
                         self._aspect_carry_right = self._get_default_carry_aspect(PostureTrack.RIGHT)
                         if hand == Hand.RIGHT:
                             self._aspect_carry_right = new_carry_aspect
                             if current_posture_state is not None:
                                 self._aspect_carry_left = current_posture_state.left
                             else:
                                 self._aspect_carry_right = self._get_default_carry_aspect(PostureTrack.LEFT)
                                 raise RuntimeError('Invalid value specified for hand: {}'.format(hand))
                         else:
                             raise RuntimeError('Invalid value specified for hand: {}'.format(hand))
                 elif hand == Hand.RIGHT:
                     self._aspect_carry_right = new_carry_aspect
                     if current_posture_state is not None:
                         self._aspect_carry_left = current_posture_state.left
                     else:
                         self._aspect_carry_right = self._get_default_carry_aspect(PostureTrack.LEFT)
                         raise RuntimeError('Invalid value specified for hand: {}'.format(hand))
                 else:
                     raise RuntimeError('Invalid value specified for hand: {}'.format(hand))
         else:
             spec_carry_posture_type = spec_carry[CARRY_POSTURE_TYPE_INDEX]
             if spec_carry_target not in var_map:
                 raise KeyError
             if spec_carry_posture_type not in var_map:
                 aop = posture_specs.get_carry_posture_aop(sim, var_map[spec_carry_target])
                 carry_posture_type = aop.affordance._carry_posture_type
                 if carry_posture_type is None:
                     raise KeyError
                 var_map += {PostureSpecVariable.POSTURE_TYPE_CARRY_OBJECT: carry_posture_type}
             carry_target = var_map[spec_carry_target]
             carry_posture_type = var_map[spec_carry_posture_type]
             if spec_carry[CARRY_HAND_INDEX] in var_map:
                 hand = var_map[spec_carry[CARRY_HAND_INDEX]]
             else:
                 for hand in sim.posture_state.get_free_hands():
                     while hand in carry_target.allowed_hands:
                         break
                 raise RuntimeError('No allowable free hand was empty.')
             new_carry_aspect = postures.create_posture(carry_posture_type, self.sim, carry_target, track=self.hand_to_track(hand))
             if hand == Hand.LEFT:
                 self._aspect_carry_left = new_carry_aspect
                 if current_posture_state is not None:
                     self._aspect_carry_right = current_posture_state.right
                 else:
                     self._aspect_carry_right = self._get_default_carry_aspect(PostureTrack.RIGHT)
                     if hand == Hand.RIGHT:
                         self._aspect_carry_right = new_carry_aspect
                         if current_posture_state is not None:
                             self._aspect_carry_left = current_posture_state.left
                         else:
                             self._aspect_carry_right = self._get_default_carry_aspect(PostureTrack.LEFT)
                             raise RuntimeError('Invalid value specified for hand: {}'.format(hand))
                     else:
                         raise RuntimeError('Invalid value specified for hand: {}'.format(hand))
             elif hand == Hand.RIGHT:
                 self._aspect_carry_right = new_carry_aspect
                 if current_posture_state is not None:
                     self._aspect_carry_left = current_posture_state.left
                 else:
                     self._aspect_carry_right = self._get_default_carry_aspect(PostureTrack.LEFT)
                     raise RuntimeError('Invalid value specified for hand: {}'.format(hand))
             else:
                 raise RuntimeError('Invalid value specified for hand: {}'.format(hand))
     elif current_posture_state is not None:
         self._aspect_carry_left = current_posture_state.left
         self._aspect_carry_right = current_posture_state.right
     elif spec_carry_target is not None:
         carry_target = var_map[spec_carry_target]
         spec_carry_posture_type = spec_carry[CARRY_POSTURE_TYPE_INDEX]
         carry_posture_type = var_map.get(spec_carry_posture_type)
         if carry_posture_type is None:
             aop = get_carry_posture_aop(sim, carry_target)
             if aop is None and invalid_expected:
                 return
             carry_posture_type = aop.affordance._carry_posture_type
         if spec_carry[CARRY_HAND_INDEX] in var_map:
             hand = var_map[spec_carry[CARRY_HAND_INDEX]]
         else:
             hand = carry_target.allowed_hands[0]
         new_carry_aspect = postures.create_posture(carry_posture_type, self.sim, carry_target, track=self.hand_to_track(hand))
         if hand == Hand.LEFT:
             self._aspect_carry_left = new_carry_aspect
             self._aspect_carry_right = self._get_default_carry_aspect(PostureTrack.RIGHT)
         else:
             self._aspect_carry_right = new_carry_aspect
             self._aspect_carry_left = self._get_default_carry_aspect(PostureTrack.LEFT)
     else:
         self._aspect_carry_left = self._get_default_carry_aspect(PostureTrack.LEFT)
         self._aspect_carry_right = self._get_default_carry_aspect(PostureTrack.RIGHT)