예제 #1
0
    def score_fn(plan):
        assert plan is not None
        initial_distance = get_distance(
            point_from_pose(initial_pose)[:2], goal_pos2d)
        final_pose = world.perception.get_pose(block_name)
        final_distance = get_distance(
            point_from_pose(final_pose)[:2], goal_pos2d)
        quat_distance = quat_angle_between(quat_from_pose(initial_pose),
                                           quat_from_pose(final_pose))
        print(
            'Initial: {:.5f} m | Final: {:.5f} | Rotation: {:.5f} rads'.format(
                initial_distance, final_distance, quat_distance))
        # TODO: compare orientation to final predicted orientation
        # TODO: record simulation time in the event that the controller gets stuck

        score = {
            'initial_distance': initial_distance,
            'final_distance': final_distance,
            'rotation': quat_distance,
            DYNAMICS: parameters_from_name,
        }

        #_, args = find_unique(lambda a: a[0] == 'push', plan)
        #control = args[-1]
        return score
예제 #2
0
    def score_fn(plan):
        assert plan is not None
        final_pose = world.get_pose(bowl_name)
        point_distance = get_distance(point_from_pose(initial_pose),
                                      point_from_pose(final_pose))  #, norm=2)
        quat_distance = quat_angle_between(quat_from_pose(initial_pose),
                                           quat_from_pose(final_pose))
        print('Translation: {:.5f} m | Rotation: {:.5f} rads'.format(
            point_distance, quat_distance))

        with ClientSaver(world.client):
            bowl_beads = get_contained_beads(bowl_body, init_beads)
            fraction_bowl = float(
                len(bowl_beads)) / len(init_beads) if init_beads else 0
            mass_in_bowl = sum(map(get_mass, bowl_beads))
            spoon_beads = get_contained_beads(world.get_body(spoon_name),
                                              init_beads)
            fraction_spoon = float(
                len(spoon_beads)) / len(init_beads) if init_beads else 0
            mass_in_spoon = sum(map(get_mass, spoon_beads))
        print('In Bowl: {:.3f} | In Spoon: {:.3f}'.format(
            fraction_bowl, fraction_spoon))
        # TODO: measure change in roll/pitch

        # TODO: could make latent parameters field
        score = {
            # Displacements
            'bowl_translation': point_distance,
            'bowl_rotation': quat_distance,
            # Masses
            'total_mass': init_mass,
            'mass_in_bowl': mass_in_bowl,
            'mass_in_spoon': mass_in_spoon,
            'spoon_mass_capacity':
            (init_mass / len(init_beads)) * spoon_capacity,
            # Counts
            'num_beads': len(init_beads),
            'bowl_beads': len(bowl_beads),
            'spoon_beads': len(spoon_beads),
            'spoon_capacity': spoon_capacity,
            # Fractions
            'fraction_in_bowl': fraction_bowl,
            'fraction_in_spoon': fraction_spoon,
            # Latent
            'bead_radius': bead_radius,
            DYNAMICS: parameters_from_name
        }

        fraction_filled = float(score['spoon_beads']) / score['spoon_capacity']
        spilled_beads = score['num_beads'] - (score['bowl_beads'] +
                                              score['spoon_beads'])
        fraction_spilled = float(spilled_beads) / score['num_beads']
        print('Fraction Filled: {} | Fraction Spilled: {}'.format(
            fraction_filled, fraction_spilled))

        #_, args = find_unique(lambda a: a[0] == 'scoop', plan)
        #control = args[-1]
        return score
예제 #3
0
 def fix_pose(self, name, pose=None, fraction=0.5):
     body = self.get_body(name)
     if pose is None:
         pose = get_pose(body)
     else:
         set_pose(body, pose)
     # TODO: can also drop in simulation
     x, y, z = point_from_pose(pose)
     roll, pitch, yaw = euler_from_quat(quat_from_pose(pose))
     quat = quat_from_euler(Euler(yaw=yaw))
     set_quat(body, quat)
     surface_name = self.get_supporting(name)
     if surface_name is None:
         return None, None
     if fraction == 0:
         new_pose = (Point(x, y, z), quat)
         return new_pose, surface_name
     surface_aabb = compute_surface_aabb(self, surface_name)
     new_z = (1 - fraction) * z + fraction * stable_z_on_aabb(
         body, surface_aabb)
     point = Point(x, y, new_z)
     set_point(body, point)
     print('{} error: roll={:.3f}, pitch={:.3f}, z-delta: {:.3f}'.format(
         name, roll, pitch, new_z - z))
     new_pose = (point, quat)
     return new_pose, surface_name
예제 #4
0
    def score_fn(plan):
        assert plan is not None
        final_pose = world.get_pose(bowl_name)
        point_distance = get_distance(point_from_pose(initial_pose),
                                      point_from_pose(final_pose))  #, norm=2)
        quat_distance = quat_angle_between(quat_from_pose(initial_pose),
                                           quat_from_pose(final_pose))
        print('Translation: {:.5f} m | Rotation: {:.5f} rads'.format(
            point_distance, quat_distance))

        with ClientSaver(world.client):
            # TODO: lift the bowl up (with particles around) to prevent scale detections
            final_bowl_beads = get_contained_beads(bowl_body, init_beads)
            fraction_bowl = safe_ratio(len(final_bowl_beads),
                                       len(init_beads),
                                       undefined=0)
            mass_in_bowl = sum(map(get_mass, final_bowl_beads))
            final_cup_beads = get_contained_beads(cup_body, init_beads)
            fraction_cup = safe_ratio(len(final_cup_beads),
                                      len(init_beads),
                                      undefined=0)
            mass_in_cup = sum(map(get_mass, final_cup_beads))
        print('In Bowl: {} | In Cup: {}'.format(fraction_bowl, fraction_cup))

        score = {
            # Displacements
            'bowl_translation': point_distance,
            'bowl_rotation': quat_distance,
            # Masses
            'mass_in_bowl': mass_in_bowl,
            'mass_in_cup': mass_in_cup,
            # Counts
            'bowl_beads': len(final_bowl_beads),
            'cup_beads': len(final_cup_beads),
            # Fractions
            'fraction_in_bowl': fraction_bowl,
            'fraction_in_cup': fraction_cup,
        }
        score.update(latent)
        # TODO: store the cup path length to bias towards shorter paths

        #_, args = find_unique(lambda a: a[0] == 'pour', plan)
        #control = args[-1]
        #feature = control['feature']
        #parameter = control['parameter']
        return score
예제 #5
0
    def score_fn(plan):
        assert plan is not None
        with ClientSaver(world.client):
            rgb_image = take_image(world, bowl_body, beads_per_color)
            values = score_image(rgb_image, bead_colors, beads_per_color)

        final_pose = perception.get_pose(bowl_name)
        point_distance = get_distance(point_from_pose(initial_pose),
                                      point_from_pose(final_pose))  #, norm=2)
        quat_distance = quat_angle_between(quat_from_pose(initial_pose),
                                           quat_from_pose(final_pose))
        print('Translation: {:.5f} m | Rotation: {:.5f} rads'.format(
            point_distance, quat_distance))

        with ClientSaver(world.client):
            all_beads = list(flatten(beads_per_color))
            bowl_beads = get_contained_beads(bowl_body, all_beads)
            fraction_bowl = float(
                len(bowl_beads)) / len(all_beads) if all_beads else 0
        print('In Bowl: {}'.format(fraction_bowl))

        with ClientSaver(world.client):
            final_dispersion = compute_dispersion(bowl_body, beads_per_color)
        print('Initial Dispersion: {:.3f} | Final Dispersion {:.3f}'.format(
            initial_distance, final_dispersion))

        score = {
            'bowl_translation': point_distance,
            'bowl_rotation': quat_distance,
            'fraction_in_bowl': fraction_bowl,
            'initial_dispersion': initial_distance,
            'final_dispersion': final_dispersion,
            'num_beads': len(all_beads),  # Beads per color
            DYNAMICS: parameters_from_name,
        }
        # TODO: include time required for stirring
        # TODO: change in dispersion

        #wait_for_user()
        #_, args = find_unique(lambda a: a[0] == 'stir', plan)
        #control = args[-1]
        return score
예제 #6
0
파일: collect_pr2.py 프로젝트: lyltc1/LTAMP
def score_poses(problem, task, ros_world):
    cup_name, bowl_name = REQUIREMENT_FNS[problem](ros_world)
    name_from_type = {'cup': cup_name, 'bowl': bowl_name}
    initial_poses = {
        ty: ros_world.get_pose(name)
        for ty, name in name_from_type.items()
    }
    final_stackings = wait_until_observation(problem, ros_world)
    #final_stackings = None
    if final_stackings is None:
        # TODO: only do this for the bad bowl
        point_distances = {ty: INF for ty in name_from_type}
        quat_distances = {ty: 2 * np.pi
                          for ty in name_from_type}  # Max rotation
    else:
        final_poses = {
            ty: ros_world.get_pose(name)
            for ty, name in name_from_type.items()
        }
        point_distances = {
            ty: get_distance(point_from_pose(initial_poses[ty]),
                             point_from_pose(final_poses[ty]))
            for ty in name_from_type
        }
        # TODO: wrap around distance for symmetric things
        quat_distances = {
            ty: quat_angle_between(quat_from_pose(initial_poses[ty]),
                                   quat_from_pose(final_poses[ty]))
            for ty in name_from_type
        }
    score = {}
    for ty in sorted(name_from_type):
        print(
            '{} | translation (m): {:.3f} | rotation (degrees): {:.3f}'.format(
                ty, point_distances[ty], math.degrees(quat_distances[ty])))
        score.update({
            '{}_translation'.format(ty): point_distances[ty],
            '{}_rotation'.format(ty): quat_distances[ty],
        })
    return score
예제 #7
0
파일: move.py 프로젝트: lyltc1/LTAMP
 def water_test(q):
     if attachment is None:
         return False
     set_joint_positions(body, joints, q)
     attachment.assign()
     attachment_pose = get_pose(attachment.child)
     pose = multiply(attachment_pose,
                     reference_pose)  # TODO: confirm not inverted
     roll, pitch, _ = euler_from_quat(quat_from_pose(pose))
     violation = (MAX_ROTATION < abs(roll)) or (MAX_ROTATION < abs(pitch))
     #if violation: # TODO: check whether different confs can be waypoints for each object
     #    print(q, violation)
     #    wait_for_user()
     return violation
예제 #8
0
def inverse_kinematics(arm, pose, torso, upper):
    from pybullet_tools.pr2_ik.ikLeft import leftIK
    from pybullet_tools.pr2_ik.ikRight import rightIK
    arm_ik = {
        'left': leftIK,
        'right': rightIK,
    }
    ik_fn = arm_ik[arm]
    pos = point_from_pose(pose)
    rot = matrix_from_quat(quat_from_pose(pose)).tolist()
    solutions = ik_fn(list(rot), list(pos), [torso, upper])
    if solutions is None:
        return []
    return solutions
예제 #9
0
파일: push.py 프로젝트: lyltc1/LTAMP
 def gen_fn(obj, pose1, surface, region=None):
     start_point = point_from_pose(pose1)
     distance_range = (0.15, 0.2) if region is None else (0.15, 0.3)
     obj_body = world.bodies[obj]
     while True:
         theta = random.uniform(-np.pi, np.pi)
         distance = random.uniform(*distance_range)
         end_point2d = np.array(start_point[:2]) + distance * unit_from_theta(theta)
         end_pose = (np.append(end_point2d, [start_point[2]]), quat_from_pose(pose1))
         set_pose(obj_body, end_pose)
         if not is_center_stable(obj_body, world.bodies[surface], above_epsilon=np.inf):
             continue
         if region is not None:
             assert region in ARMS
             if not reachable_test(region, obj, end_pose):
                 continue
         yield end_point2d,
예제 #10
0
파일: push.py 프로젝트: lyltc1/LTAMP
def get_end_pose(initial_pose, goal_pos2d):
    initial_z = point_from_pose(initial_pose)[2]
    orientation = quat_from_pose(initial_pose)
    goal_x, goal_y = goal_pos2d
    end_pose = ([goal_x, goal_y, initial_z], orientation)
    return end_pose
예제 #11
0
    def gen(obj_name, surface_name):
        obj_body = world.get_body(obj_name)
        surface_body = world.kitchen
        if surface_name in ENV_SURFACES:
            surface_body = world.environment_bodies[surface_name]
        surface_aabb = compute_surface_aabb(world, surface_name)
        learned_poses = load_placements(world, surface_name) if learned else [
        ]  # TODO: GROW_PLACEMENT

        yaw_range = (-np.pi, np.pi)
        #if world.is_real():
        #    center = -np.pi/4
        #    half_extent = np.pi / 16
        #    yaw_range = (center-half_extent, center+half_extent)
        while True:
            for _ in range(max_attempts):
                if surface_name in STOVES:
                    surface_link = link_from_name(world.kitchen, surface_name)
                    world_from_surface = get_link_pose(world.kitchen,
                                                       surface_link)
                    z = stable_z_on_aabb(
                        obj_body,
                        surface_aabb) - point_from_pose(world_from_surface)[2]
                    yaw = random.uniform(*yaw_range)
                    body_pose_surface = Pose(Point(z=z + z_offset),
                                             Euler(yaw=yaw))
                    body_pose_world = multiply(world_from_surface,
                                               body_pose_surface)
                elif learned:
                    if not learned_poses:
                        return
                    surface_pose_world = get_surface_reference_pose(
                        surface_body, surface_name)
                    sampled_pose_surface = multiply(
                        surface_pose_world, random.choice(learned_poses))
                    [x, y, _] = point_from_pose(sampled_pose_surface)
                    _, _, yaw = euler_from_quat(
                        quat_from_pose(sampled_pose_surface))
                    dx, dy = np.random.normal(
                        scale=pos_scale, size=2) if pos_scale else np.zeros(2)
                    # TODO: avoid reloading
                    z = stable_z_on_aabb(obj_body, surface_aabb)
                    yaw = random.uniform(*yaw_range)
                    #yaw = wrap_angle(yaw + np.random.normal(scale=rot_scale))
                    quat = quat_from_euler(Euler(yaw=yaw))
                    body_pose_world = ([x + dx, y + dy, z + z_offset], quat)
                    # TODO: project onto the surface
                else:
                    # TODO: halton sequence
                    # unit_generator(d, use_halton=True)
                    body_pose_world = sample_placement_on_aabb(
                        obj_body, surface_aabb, epsilon=z_offset, percent=2.0)
                    if body_pose_world is None:
                        continue  # return?
                if visibility and not is_visible_by_camera(
                        world, point_from_pose(body_pose_world)):
                    continue
                # TODO: make sure the surface is open when doing this

                robust = True
                if robust_radius != 0.:
                    for theta in np.linspace(0, 5 * np.pi, num=8):
                        x, y = robust_radius * unit_from_theta(theta)
                        delta_body = Pose(Point(x, y))
                        delta_world = multiply(body_pose_world, delta_body)
                        set_pose(obj_body, delta_world)
                        if not test_supported(world,
                                              obj_body,
                                              surface_name,
                                              collisions=collisions):
                            robust = False
                            break

                set_pose(obj_body, body_pose_world)
                if robust and test_supported(
                        world, obj_body, surface_name, collisions=collisions):
                    rp = create_relative_pose(world, obj_name, surface_name)
                    yield (rp, )
                    break
            else:
                yield None
예제 #12
0
def pdddlstream_from_problem(belief,
                             additional_init=[],
                             fixed_base=True,
                             **kwargs):
    world = belief.world  # One world per state
    task = world.task  # One task per world
    print(task)
    domain_pddl = read(get_file_path(__file__, '../pddl/domain.pddl'))
    # TODO: repackage stream outputs to avoid recomputation

    # Despite the base not moving, it could be re-estimated
    init_bq = belief.base_conf
    init_aq = belief.arm_conf
    init_gq = belief.gripper_conf

    carry_aq = world.carry_conf
    init_aq = carry_aq if are_confs_close(init_aq, carry_aq) else init_aq

    # TODO: the following doesn't work. Maybe because carry_conf is used elsewhere
    #carry_aq = init_aq if are_confs_close(init_aq, world.carry_conf) else world.carry_conf
    #calibrate_aq = init_aq if are_confs_close(init_aq, world.calibrate_conf) else world.calibrate_conf

    # Don't need this now that returning to old confs
    #open_gq = init_gq if are_confs_close(init_gq, world.open_gq) else world.open_gq
    #closed_gq = init_gq if are_confs_close(init_gq, world.closed_gq) else world.closed_gq
    open_gq = world.open_gq
    closed_gq = world.closed_gq

    constant_map = {
        '@world': 'world',
        '@gripper': 'gripper',
        '@stove': 'stove',
        '@none': None,
        '@rest_aq': carry_aq,
        #'@calibrate_aq': calibrate_aq,
        '@open_gq': open_gq,
        '@closed_gq': closed_gq,
        '@open': OPEN,
        '@closed': CLOSED,
        '@top': TOP_GRASP,
        '@side': SIDE_GRASP,
        '@bq0': init_bq,
    }
    top_joint = JOINT_TEMPLATE.format(TOP_DRAWER)
    bottom_joint = JOINT_TEMPLATE.format(BOTTOM_DRAWER)

    init = [
        ('BConf', init_bq),
        ('AtBConf', init_bq),
        ('AConf', init_bq, carry_aq),
        #('RestAConf', carry_aq),
        #('AConf', init_bq, calibrate_aq),
        (
            'Stationary', ),
        ('AConf', init_bq, init_aq),
        ('AtAConf', init_aq),
        ('GConf', open_gq),
        ('GConf', closed_gq),
        ('Grasp', None, None),
        ('AtGrasp', None, None),
        ('Above', top_joint, bottom_joint),
        ('Adjacent', top_joint, bottom_joint),
        ('Adjacent', bottom_joint, top_joint),
        ('Calibrated', ),
        ('CanMoveBase', ),
        ('CanMoveArm', ),
        ('CanMoveGripper', ),
    ] + list(task.init) + list(additional_init)
    for action_name, cost in ACTION_COSTS.items():
        function_name = '{}Cost'.format(title_from_snake(action_name))
        function = (function_name, )
        init.append(Equal(function, cost))  # TODO: stove state
    init += [('Stackable', name, surface) for name, surface in task.goal_on.items()] + \
            [('Stackable', name, stove) for name, stove in product(task.goal_cooked, STOVES)] + \
            [('Pressed', name) for name in belief.pressed] + \
            [('Cookable', name) for name in task.goal_cooked] + \
            [('Cooked', name) for name in belief.cooked] + \
            [('Status', status) for status in DOOR_STATUSES] + \
            [('Knob', knob) for knob in KNOBS] + \
            [('Joint', knob) for knob in KNOBS] + \
            [('Liquid', liquid) for _, liquid in task.init_liquid] + \
            [('HasLiquid', cup, liquid) for cup, liquid in belief.liquid] + \
            [('StoveKnob', STOVE_TEMPLATE.format(loc), KNOB_TEMPLATE.format(loc)) for loc in STOVE_LOCATIONS] + \
            [('GraspType', ty) for ty in task.grasp_types]  # TODO: grasp_type per object
    #[('Type', obj_name, 'stove') for obj_name in STOVES] + \
    #[('Camera', name) for name in world.cameras]
    if task.movable_base:
        init.append(('MovableBase', ))
    if fixed_base:
        init.append(('InitBConf', init_bq))
    if task.noisy_base:
        init.append(('NoisyBase', ))

    compute_pose_kin = get_compute_pose_kin(world)
    compute_angle_kin = get_compute_angle_kin(world)

    initial_poses = {}
    for joint_name, init_conf in belief.door_confs.items():
        if joint_name in DRAWER_JOINTS:
            init.append(('Drawer', joint_name))
        if joint_name in CABINET_JOINTS:
            init.append(('Cabinet', joint_name))
        joint = joint_from_name(world.kitchen, joint_name)
        surface_name = surface_from_joint(joint_name)
        init.append(('SurfaceJoint', surface_name, joint_name))
        # Relies on the fact that drawers have identical surface and link names
        link_name = get_link_name(world.kitchen, child_link_from_joint(joint))
        #link_name = str(link_name.decode('UTF-8'))
        #link_name = str(link_name.encode('ascii','ignore'))
        for conf in {
                init_conf, world.open_kitchen_confs[joint],
                world.closed_kitchen_confs[joint]
        }:
            # TODO: return to initial poses?
            world_pose, = compute_angle_kin(link_name, joint_name, conf)
            init.extend([
                ('Joint', joint_name),
                ('Angle', joint_name, conf),
                ('Obstacle', link_name),
                ('AngleKin', link_name, world_pose, joint_name, conf),
                ('WorldPose', link_name, world_pose),
            ])
            if joint in world.kitchen_joints:
                init.extend([
                    ('Sample', world_pose),
                    #('Value', world_pose), # comment out?
                ])
            if conf == init_conf:
                initial_poses[link_name] = world_pose
                init.extend([
                    ('AtAngle', joint_name, conf),
                    ('AtWorldPose', link_name, world_pose),
                ])

    for surface_name in ALL_SURFACES:
        if surface_name in OPEN_SURFACES:
            init.append(('Counter', surface_name))  # Fixed surface
        if surface_name in DRAWERS:
            init.append(('Drawer', surface_name))
        surface = surface_from_name(surface_name)
        surface_link = link_from_name(world.kitchen, surface.link)
        parent_joint = parent_joint_from_link(surface_link)
        if parent_joint not in world.kitchen_joints:
            # TODO: attach to world frame?
            world_pose = RelPose(world.kitchen, surface_link, init=True)
            initial_poses[surface_name] = world_pose
            init += [
                #('RelPose', surface_name, world_pose, 'world'),
                ('WorldPose', surface_name, world_pose),
                #('AtRelPose', surface_name, world_pose, 'world'),
                ('AtWorldPose', surface_name, world_pose),
                ('Sample', world_pose),
                #('Value', world_pose),
            ]
        init.extend([
            ('CheckNearby', surface_name),
            #('InitPose', world_pose),
            ('Localized', surface_name),
        ])
        for grasp_type in task.grasp_types:
            if (surface_name in OPEN_SURFACES) or has_place_database(
                    world.robot_name, surface_name, grasp_type):
                init.append(('AdmitsGraspType', surface_name, grasp_type))

    if belief.grasped is None:
        init.extend([
            ('HandEmpty', ),
            ('GConf', init_gq),
            ('AtGConf', init_gq),
        ])
    else:
        obj_name = belief.grasped.body_name
        assert obj_name not in belief.pose_dists
        grasp = belief.grasped
        init += [
            # Static
            #('Graspable', obj_name),
            ('Grasp', obj_name, grasp),
            ('IsGraspType', obj_name, grasp, grasp.grasp_type),
            # Fluent
            ('AtGrasp', obj_name, grasp),
            ('Holding', obj_name),
            ('Localized', obj_name),
        ]
        init.extend(('ValidGraspType', obj_name, grasp_type)
                    for grasp_type in task.grasp_types
                    if implies(world.is_real(),
                               is_valid_grasp_type(obj_name, grasp_type)))

    for obj_name in world.movable:
        obj_type = type_from_name(obj_name)
        if obj_type in BOWLS:
            init.append(('Bowl', obj_name))
        else:
            init.append(
                ('Obstacle', obj_name))  # TODO: hack to place within bowls
        if obj_type in COOKABLE:
            init.append(('Cookable', obj_name))
        if obj_type in POURABLE:
            init.append(('Pourable', obj_name))
        init += [
            ('Entity', obj_name),
            ('CheckNearby', obj_name),
        ] + [('Stackable', obj_name, counter)
             for counter in set(ALL_SURFACES) & set(COUNTERS)]

    # TODO: track poses over time to produce estimates
    for obj_name, pose_dist in belief.pose_dists.items():
        dist_support = pose_dist.dist.support()
        localized = pose_dist.is_localized()
        graspable = True
        if localized:
            init.append(('Localized', obj_name))
            [rel_pose] = dist_support
            roll, pitch, yaw = euler_from_quat(
                quat_from_pose(rel_pose.get_reference_from_body()))
            if (MAX_ERROR < abs(roll)) or (MAX_ERROR < abs(pitch)):
                graspable = False
                print(
                    '{} has an invalid orientation: roll={:.3f}, pitch={:.3f}'.
                    format(obj_name, roll, pitch))
        if graspable:
            #init.append(('Graspable', obj_name))
            init.extend(('ValidGraspType', obj_name, grasp_type)
                        for grasp_type in task.grasp_types
                        if implies(world.is_real(),
                                   is_valid_grasp_type(obj_name, grasp_type)))

        # Could also fully decompose into points (but many samples)
        # Could immediately add likely points for collision checking
        for rel_pose in (dist_support if localized else pose_dist.decompose()):
            surface_name = rel_pose.support
            if surface_name is None:
                # Treats as obstacle
                # TODO: could temporarily add to fixed
                world_pose = rel_pose
                init += [
                    ('WorldPose', obj_name, world_pose),
                    ('AtWorldPose', obj_name, world_pose),
                ]
                poses = [world_pose]
                #raise RuntimeError(obj_name, supporting)
            else:
                surface_pose = initial_poses[surface_name]
                world_pose, = compute_pose_kin(obj_name, rel_pose,
                                               surface_name, surface_pose)
                init += [
                    # Static
                    ('RelPose', obj_name, rel_pose, surface_name),
                    ('WorldPose', obj_name, world_pose),
                    ('PoseKin', obj_name, world_pose, rel_pose, surface_name,
                     surface_pose),
                    # Fluent
                    ('AtRelPose', obj_name, rel_pose, surface_name),
                    ('AtWorldPose', obj_name, world_pose),
                ]
                if localized:
                    init.append(('On', obj_name, surface_name))
                poses = [rel_pose, world_pose]
            for pose in poses:
                if isinstance(pose, PoseDist):
                    init.append(('Dist', pose))
                else:
                    init.extend([('Sample', pose)])  #, ('Value', pose)])

    #for body, ty in problem.body_types:
    #    init += [('Type', body, ty)]
    #bodies_from_type = get_bodies_from_type(problem)
    #bodies = bodies_from_type[get_parameter_name(ty)] if is_parameter(ty) else [ty]

    goal_formula = get_goal(belief, init)
    stream_pddl, stream_map = get_streams(world,
                                          teleport_base=task.teleport_base,
                                          **kwargs)

    print('Constants:', constant_map)
    print('Init:', sorted(init, key=lambda f: f[0]))
    print('Goal:', goal_formula)
    #print('Streams:', stream_map.keys()) # DEBUG

    return PDDLProblem(domain_pddl, constant_map, stream_pddl, stream_map,
                       init, goal_formula)