diff --git a/scripts/experiments/debug/likelihood_debug.ipynb b/scripts/experiments/debug/likelihood_debug.ipynb index 69983532..a585d41a 100644 --- a/scripts/experiments/debug/likelihood_debug.ipynb +++ b/scripts/experiments/debug/likelihood_debug.ipynb @@ -29,7 +29,7 @@ "output_type": "stream", "text": [ "You can open the visualizer by visiting the following URL:\n", - "http://127.0.0.1:7012/static/\n" + "http://127.0.0.1:7014/static/\n" ] } ], @@ -39,7 +39,59 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 3, + "id": "d705f5f3-499d-4f43-b689-41ba648a2a1f", + "metadata": {}, + "outputs": [], + "source": [ + "model_dir = os.path.join(b.utils.get_assets_dir(),\"ycb_video_models/models/025_mug\")\n", + "mesh = b.utils.mesh.load_mesh(os.path.join(model_dir, \"textured_simple.obj\"))\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "7405b61a-4464-4ac3-ae86-f9eecc0965eb", + "metadata": {}, + "outputs": [], + "source": [ + "b.clear()\n", + "num_colors = 2\n", + "colors = b.viz.distinct_colors(num_colors)\n", + "offset = b.transform_from_pos(jnp.array([0.003, 0.0,0.0]))\n", + "for i in range(num_colors):\n", + " b.show_trimesh(f\"{i}\", mesh, color=colors[i])\n", + " b.set_pose(f\"{i}\", offset @ b.transform_from_axis_angle(jnp.array([0.0, 0.0, 1.0]), i))" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "c5eab559-3fd7-4964-a903-9f1a50ad3842", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(Array([0.116966, 0.093075, 0.081384], dtype=float32),\n", + " Array([[1.0000000e+00, 0.0000000e+00, 0.0000000e+00, 8.2690008e-03],\n", + " [0.0000000e+00, 1.0000000e+00, 0.0000000e+00, 6.1250106e-04],\n", + " [0.0000000e+00, 0.0000000e+00, 1.0000000e+00, 1.6890001e-03],\n", + " [0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 1.0000000e+00]], dtype=float32))" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "b.utils.aabb(mesh.vertices)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, "id": "a42856ac-4db2-43cd-a4e7-6b93bc550f12", "metadata": {}, "outputs": [ @@ -62,7 +114,7 @@ "intrinsics = b.Intrinsics(\n", " height=100,\n", " width=100,\n", - " fx=50.0, fy=50.0,\n", + " fx=200.0, fy=200.0,\n", " cx=50.0, cy=50.0,\n", " near=0.0001, far=2.0\n", ")\n", @@ -73,11 +125,29 @@ "for idx in range(1,22):\n", " mesh_path = os.path.join(model_dir,\"obj_\" + \"{}\".format(idx).rjust(6, '0') + \".ply\")\n", " b.RENDERER.add_mesh_from_file(mesh_path, scaling_factor=1.0/1000.0)\n", + "# b.RENDERER.add_mesh_from_file(os.path.join(b.utils.get_assets_dir(), \"sample_objs/cube.obj\"), scaling_factor=1.0/10.0)\n", "b.RENDERER.add_mesh_from_file(os.path.join(b.utils.get_assets_dir(), \"sample_objs/cube.obj\"), scaling_factor=1.0/1000000000.0)\n", - "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cd77205e-2735-4737-bc2a-512427f8aff9", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "f4648f31-caf1-4792-bd83-9d652a8c5e4b", + "metadata": {}, + "outputs": [], + "source": [ "table_pose = b.t3d.inverse_pose(\n", " b.t3d.transform_from_pos_target_up(\n", - " jnp.array([0.0, 0.2, .03]),\n", + " jnp.array([0.0, 0.8, .15]),\n", " jnp.array([0.0, 0.0, 0.0]),\n", " jnp.array([0.0, 0.0, 1.0]),\n", " )\n", @@ -86,7 +156,7 @@ }, { "cell_type": "code", - "execution_count": 151, + "execution_count": 8, "id": "3277a542-3698-40f7-a998-d7febb9591eb", "metadata": {}, "outputs": [], @@ -106,25 +176,19 @@ " outlier_volume: float,\n", " filter_size: int,\n", "):\n", - " filter_data = jax.lax.dynamic_slice(rendered_xyz_padded, (ij[0], ij[1], 0), (2*filter_size + 1, 2*filter_size + 1, 3))\n", - " distances = jnp.linalg.norm(\n", - " observed_xyz[ij[0], ij[1], :3] - filter_data,\n", - " axis=-1\n", + " distances = (\n", + " observed_xyz[ij[0], ij[1], :3] - \n", + " jax.lax.dynamic_slice(rendered_xyz_padded, (ij[0], ij[1], 0), (2*filter_size + 1, 2*filter_size + 1, 3))\n", " )\n", - " squared_filter_z = filter_data[:,:,2]**2\n", - " # probability = jax.scipy.special.logsumexp(\n", - " # jax.scipy.stats.norm.logpdf(\n", - " # distances,\n", - " # loc=0.0,\n", - " # scale=jnp.sqrt(variance)\n", - " # ) + jnp.log(squared_distances)\n", - " # ) - jnp.log(squared_distances.sum())\n", - " probability = jax.scipy.stats.norm.logpdf(\n", - " distances,\n", - " loc=0.0,\n", - " scale=jnp.sqrt(variance)\n", - " ) + jnp.log(squared_filter_z) - jnp.log(squared_filter_z.sum())\n", - " return jnp.logaddexp(probability.max() + jnp.log(1.0 - outlier_prob), jnp.log(outlier_prob) - jnp.log(outlier_volume))\n", + " probability = jax.scipy.special.logsumexp(\n", + " jax.scipy.stats.norm.logpdf(\n", + " distances,\n", + " loc=0.0,\n", + " scale=jnp.sqrt(variance)\n", + " ).sum(-1) - jnp.log(observed_xyz.shape[0] * observed_xyz.shape[1])\n", + " )\n", + " return jnp.logaddexp(probability + jnp.log(1.0 - outlier_prob), jnp.log(outlier_prob) - jnp.log(outlier_volume))\n", + "\n", "\n", "def threedp3_likelihood_per_pixel(\n", " observed_xyz: jnp.ndarray,\n", @@ -187,7 +251,48 @@ }, { "cell_type": "code", - "execution_count": 89, + "execution_count": 9, + "id": "4a64e88e-4df4-4ae4-bd21-24c04fdc7782", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['002_master_chef_can',\n", + " '003_cracker_box',\n", + " '004_sugar_box',\n", + " '005_tomato_soup_can',\n", + " '006_mustard_bottle',\n", + " '007_tuna_fish_can',\n", + " '008_pudding_box',\n", + " '009_gelatin_box',\n", + " '010_potted_meat_can',\n", + " '011_banana',\n", + " '019_pitcher_base',\n", + " '021_bleach_cleanser',\n", + " '024_bowl',\n", + " '025_mug',\n", + " '035_power_drill',\n", + " '036_wood_block',\n", + " '037_scissors',\n", + " '040_large_marker',\n", + " '051_large_clamp',\n", + " '052_extra_large_clamp',\n", + " '061_foam_brick']" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "b.utils.ycb_loader.MODEL_NAMES" + ] + }, + { + "cell_type": "code", + "execution_count": 10, "id": "772bb4b0-af42-4842-9af6-94752b30a707", "metadata": {}, "outputs": [], @@ -196,10 +301,10 @@ " mval = image[image < image.max()].max()\n", " return b.get_depth_image(image, max=mval)\n", "\n", - "def get_poses_non_jit(contact_params, id):\n", + "def get_poses_non_jit(contact_params, id_table, id):\n", " sg = b.scene_graph.SceneGraph(\n", " root_poses=jnp.array([table_pose, jnp.eye(4)]),\n", - " box_dimensions=jnp.array([b.RENDERER.model_box_dims[21], b.RENDERER.model_box_dims[id]]),\n", + " box_dimensions=jnp.array([b.RENDERER.model_box_dims[id_table], b.RENDERER.model_box_dims[id]]),\n", " parents=jnp.array([-1, 0]),\n", " contact_params=jnp.array([jnp.zeros(3), contact_params]),\n", " face_parent=jnp.array([-1,2]),\n", @@ -210,15 +315,18 @@ "get_poses = jax.jit(get_poses_non_jit)\n", "\n", "def render_image_non_jit(contact_params):\n", + " id_table = 21\n", " id = 13\n", - " poses = get_poses_non_jit(contact_params, id)\n", + " poses = get_poses_non_jit(contact_params, id_table, id)\n", " img = b.RENDERER.render(\n", - " poses , jnp.array([21, id])\n", + " poses , jnp.array([id_table, id])\n", " )[...,:3]\n", " return img\n", "render_image = jax.jit(render_image_non_jit)\n", "\n", - "scorer = lambda obs, c, var, outlier_prob, outlier_volume: threedp3_likelihood(obs, render_image_non_jit(c), var, outlier_prob, outlier_volume, 4)\n", + "scorer = lambda obs, c, var, outlier_prob, outlier_volume: threedp3_likelihood(\n", + " obs, render_image_non_jit(c), var, outlier_prob, outlier_volume, 4\n", + ")\n", "scorer_jit = jax.jit(scorer)\n", "sweep_scorer = jax.jit(jax.vmap(\n", " scorer \n", @@ -233,12 +341,12 @@ }, { "cell_type": "code", - "execution_count": 90, + "execution_count": 11, "id": "fb05d62f-8b7f-4ed2-873c-530302c10964", "metadata": {}, "outputs": [], "source": [ - "width = 0.03\n", + "width = 0.01\n", "ang = jnp.pi\n", "contact_param_deltas = b.utils.make_translation_grid_enumeration_3d(\n", " -width, -width, -ang,\n", @@ -249,7 +357,7 @@ }, { "cell_type": "code", - "execution_count": 91, + "execution_count": 12, "id": "34bdcc5b-c781-4f35-bc8a-e89d35033465", "metadata": {}, "outputs": [], @@ -259,183 +367,671 @@ }, { "cell_type": "code", - "execution_count": 276, + "execution_count": 16, "id": "02d80355-07ff-49af-8233-71d276f95303", "metadata": {}, "outputs": [], "source": [ - "variance = 0.00001\n", - "outlier_prob = 0.0\n", + "variance = 0.0001\n", + "outlier_prob = 0.0001\n", "outlier_volume = 1.0" ] }, { "cell_type": "code", - "execution_count": null, - "id": "04a1ce66-a057-4f6e-bc76-f51fa88b54b5", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 277, + "execution_count": 18, "id": "cae7a753-e4f7-4cc3-beb5-5d149e37119c", - "metadata": { - "jupyter": { - "source_hidden": true - } - }, - "outputs": [], - "source": [ - "# for experiment_iteration in tqdm(range(50)):\n", - "# high = jnp.array([0.1, 0.1, jnp.pi])\n", - "# low = jnp.array([-0.1, -0.1, -jnp.pi])\n", - "# key = jax.random.split(key, 1)[0]\n", - " \n", - "# gt_contact = jax.random.uniform(key, shape=(3,)) * (high - low) + low\n", - "# gt_contact = gt_contact.at[2].set(jnp.pi)\n", - "# # gt_contact = jnp.array([-0.03, -0.09, -0.51 ])\n", - "# # gt_contact = jnp.array([-0.03, -0.09, -0.51 + jnp.pi ])\n", - "# observation = render_image(gt_contact)\n", - "# get_depth_image(observation[...,2])\n", - " \n", - "# contact_param_grid = gt_contact + contact_param_deltas\n", - " \n", - "# weights = jnp.concatenate([\n", - "# sweep_scorer(observation, cp, variance, outlier_prob, outlier_volume)\n", - "# for cp in jnp.array_split(contact_param_grid, 100)\n", - "# ],axis=0)\n", - " \n", - "# key2 = jax.random.PRNGKey(0)\n", - "# sampled_indices = jax.random.categorical(key2, weights.reshape(-1), shape=(1000,))\n", - "# sampled_indices = jnp.unravel_index(sampled_indices, weights.shape)[0]\n", - "# sampled_params = contact_param_grid[sampled_indices]\n", - "# actual_params = gt_contact\n", - " \n", - "# fig = plt.figure(constrained_layout=True)\n", - "# widths = [1, 1]\n", - "# heights = [2]\n", - "# spec = fig.add_gridspec(ncols=2, nrows=1, width_ratios=widths,\n", - "# height_ratios=heights)\n", - " \n", - "# ax = fig.add_subplot(spec[0, 0])\n", - "# ax.imshow(jnp.array(get_depth_image(observation[...,2])))\n", - "# ax.get_xaxis().set_visible(False)\n", - "# ax.get_yaxis().set_visible(False)\n", - "# ax.set_title(f\"Observation (params {gt_contact[0]:0.2f} {gt_contact[1]:0.2f} {gt_contact[2]:0.2f})\")\n", - " \n", - " \n", - "# ax = fig.add_subplot(spec[0, 1])\n", - "# ax.set_aspect(1.0)\n", - "# circ = plt.Circle((0, 0), radius=1, edgecolor='black', facecolor='None', linestyle=\"--\", linewidth=0.5)\n", - "# ax.add_patch(circ)\n", - "# ax.set_xlim(-2.0, 2.0)\n", - "# ax.set_ylim(-2.0, 2.0)\n", - "# ax.get_xaxis().set_visible(False)\n", - "# ax.get_yaxis().set_visible(False)\n", - "# ax.scatter(-jnp.sin(sampled_params[:,2]),-jnp.cos(sampled_params[:,2]),label=\"Posterior Samples\", alpha=0.5, s=15)\n", - "# ax.scatter(-jnp.sin(actual_params[2]),-jnp.cos(actual_params[2]), color=(1.0, 0.0, 0.0),label=\"Actual\", alpha=0.9, s=10)\n", - "# ax.set_title(\"Posterior on Orientation (top view)\")\n", - "# ax.legend(fontsize=7)\n", - "# # plt.show()\n", - "# plt.savefig(f'{experiment_iteration:05d}.png')\n", - "# plt.clf()" - ] - }, - { - "cell_type": "code", - "execution_count": 278, - "id": "49c9bee1-c81d-43a9-b720-244b9c16c892", "metadata": {}, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + " 40%|███████████████▌ | 20/50 [01:24<02:08, 4.29s/it]/var/tmp/ipykernel_624622/488378740.py:26: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`). Consider using `matplotlib.pyplot.close()`.\n", + " fig = plt.figure(constrained_layout=True)\n", + "100%|███████████████████████████████████████| 50/50 [03:28<00:00, 4.18s/it]\n" + ] + }, { "data": { - "image/png": "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IiIiZPLkybJgwQL5+++/ZdCgQRIaGpruDtgHH3ygO7FHR0dLqVKlZMyYMbJw4UJ59dVXpWrVqmK1WuXvv/8WkVvfuhcuXCgApHv37rJ8+XJZvny57Ny5U3fsqgEDBggA6dmzpyxYsED69+8vAKRbt2665cqVKydVq1aVEiVKyAsvvCDz58+XBg0aiMlkkj179nh9DxITE8Xf31/GjBmT7rnWrVtLZGSkFC9eXEaNGiVvvfWWtGzZUgDIsmXLXMv5cvwi2gekRo0aUrFiRZk5c6bMmTNHjh8/nult1KtXT2rUqCFvvPGGTJgwQWw2mzRt2lReeOEFad68ubz11lvy1FNPiclk0iWD58+fl7CwMKlSpYq89tprsnTpUnnxxRelevXqXl8nTzZv3iwAZOXKlemea9mypTRo0MDr+tOmTRMAcv78ed38hIQEMZvNbt+XS5cuyYULF2TXrl0yaNAgASBLlizxup9Tp04JAJk1a1a65/r16yfh4eFe1//oo48EgPzxxx/pnouKipIHH3xQN+/KlStSsmRJ1x3BrCSMMTExcv78efnrr7+kc+fOAkA2btyYqW34kjB27NhR7r33XhERrwlj6ms4b968TMXgK08J49y5cwWALFq0yBVjRueFjP7OMzof7dmzR0JCQqRGjRoya9YsmT9/vtx1111iMpl0F5rUmGvUqCGtW7eWefPmuX5K4S5hTD3PtW/fXubNmyejRo0Si8UijRs31l34W7duLSVLlpSIiAh58sknZfHixfLll196fO2+//578fPzkypVqsirr74qkydPlmLFiklYWJjb/devX18efPBBefvtt2XIkCECQJ555hmv78/BgwcFgNtkIFXq+alv374+HUvahDGz1626detKqVKlZOrUqfLmm29KxYoVJSAgQGJiYkTkVnLQu3dvASBz5sxxvc+pd4EbN24sAwcOlDlz5si8efOkQ4cOAkDmz5/v2s+aNWskKipKqlWr5lo/9XPoLmFMfd8bN24sc+bMkeeee078/f2lfPnyui8GqT8dqVmzpgwaNEgWLlwoPXr0EADpklZ32rdvn+78mtHxZuaaWqVKFQkNDZXnnntO3njjDaldu7aYzeYMz0G+5g3uEkZfP3d16tSRHj16uB6vWbNGzGazANBd82vWrCk9e/bUxZGUlCT+/v6uxDWn+JwwXr58WQCk+wNP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wosvvqhbZtWqVahYsSK++OIL3b4mTZqkWy4zcZQrVw5OpxOHDh1ynagA4Pz587h8+TLKlSuXxSPSK1u2LPz9/XH06FG3z585cybdt/ODBw8CgOv98PX4vcmObWRG06ZN0bRpU0yfPh2ffPIJ+vbti08//RRDhgxxu/wzzzyDfv36uR6n3pGoVasW/Pz8sHXrVl0P+omJidixY0eGverXq1cPwK1STseOHV3zt27dCqfT6Xrem/j4+AzLR6VLl0ZERAS2bt2a7rk///wzw/2ocaYmh8Ctv49Tp07hiSeeAACcOHECAPDggw+m28bp06dRoUIFzJkzB08//bTX/bkTHx/v9g5nVly6dAnXrl3Dq6++ildffTXd8xUqVEDXrl3x5ZdfuuadPn0aiYmJus9jbsvsecHb37mn81HFihUBAFarFe3bt8/W2AHgwIEDrn0Atz4rR48ezfK+1O2mtX//fhQrVixdlSQrqlSpgipVquDLL7/E3Llz3ZamP/zwQwDwuZP6tLLruqXytJ1169YhISEBa9eu1d2pTFv29raNtNT3IrWMnurAgQPZdt0Cbt2xdHfd8hRrZj87qXf81O2lvfZ54kvekFZmP3etWrXCr7/+igoVKqBevXooUqQI6tati5CQEHz33XfYvn272+pJcnIyTp48iS5dumS4j9uRqZFexo8fD39/fwwdOjRd7/cXL17EsGHDEBAQgPHjx6dbd8GCBbrHqaNe3H///a7100q9oKVeUB5++GGcPn0aS5cuTbdsfHy8z7+HMpvN6NmzJ9atW4fly5cjOTk53W3l1G9J6re6P/74A//73/90ywUEBACATz3QpyYPb775pm5+6jfPTp06+RR/RqxWKxo1auQ2kQBu/XEtXrzY9TgxMRGLFy9GREQEGjZsCMD34/cmO7bhi0uXLqX79p32b8edGjVqoH379q5/qcceEhKC9u3b46OPPtKVqpYvX45r167hoYcecs27ceMG9u/fr/vtSNu2bREeHo6FCxfq9rdw4UIEBATo3ue05SjgVmnkxx9/zPCOFHDrt6Pr16/HyZMnXfN+/PFHHDx4UBdnUlIS9u/fr7sbWbNmTVSrVg1LlizR/V5y4cKFMJlM6Nmzp+t41qxZk+5fREQEGjVqhDVr1qBz584eY0xOTnZ71+DPP//E7t270x3n/v37XUlqZhQvXtxtnHff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DREA3mEkIiLKO6ZNA9q2BQYMuPX/tGlGR0QEgAkjERGRoUQEN27cwLVff4XMng2nCFKCguB0OoHZsxH/22+3pokMxJI0ZasfTpqU6UTdc8PMp1zToa21krTVqZWIHdDKow5dK2llW0orabVFsK4sC8CptKBWWxc7zeJ22mzRYk/bUtm163RzlI+QT2NJK9NqB93KtFj0e1E761bL6WrJ3akcu8mqjaltM2vTwSnaa8UyNFHuERFs374du3fvxtWrVzFq1Cj07t0b169fR6dOnVCvXj28+eabaHbmDJ5MSEC8zYaka9dgEkGIyYR3XngB34eEoEOHDrjzzjsxY8YMlCpVCk8//TSio6Nx9epV1KlTB6VKldLtt/xzX6eL5djMTrl12FTAMGEkIiLKJrGxsYiNjQUATJgwAdevX8fUqVMRFxeHoKAgVKtWDSaTCe+//z4cDq2rsU8//fTWbxfbtkWgCBAcDNy4AZhMeHLOHDyp/Jbx008/xblz51C0aFHExsbiwIED+P777zFz5kz07t0btWrVwnvxjdzGV/65r5k0UpYwYSQiIsqia9euYePGjXjggQcwcuRIJCQkoGvXrujUqRPeffddBAUFuV1PTRZdGjQAxo0DZs8GrlwBrFZg/Ph0DV9sNhvKli0LAGjatCmaNm3qem758uXYtWsX3vviv35X5b+qhCl9fYQoM5gwUq6JuaCVRMOV6q3S2Bd2pSRtUVpJW0zaQhaLtkyyUmoWpSU1AKT4aevrWhR76MRb1zJa2ZTJQ+n4vxnapKfW0LrF3Ze9dZ1zW3Vr6MrmycpxqCV3dSxpk9LJeaBFaxkdkqh/fYgoa06dOoXLly/j9OnTWLRoEe69916kpKRg6dKlt7/xCROAjh2z3Era4XCgSZMmwBf/laPVRFEEEMHnn3+OHj16wOypZwciN5gwEhERZSA6OhrFihVDnz594HA4MGjQINx777249957s39nDRrkTHc6JhNgMqFx48bYsmULXn75ZTRp0gTjx49HSEhI9u+PChQmjERERB4cOnQIU6ZMQUJCAt555x188sknMOXz8m758uVRvnx5bNiwAb///jvsdjtGjx6Ne++9F/fddx/vPJJbTBgp16zap5VWJyj9XSt9UcMuaitp9619TUorafgpraStXlpJW9y3klZbHXtqMa22fTan7YlKaeFtShG4o2v1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NDoc+k9MTAwuXbqEV199FZ07dzY6HLpNTBiJiKhAmD59Ot577z1s2LDB6FAKvVWrVmHw4MG44447ULNmTaPDoWzAhJGIiAqEgIAALF++HHfffTfmzZvHbncMcvLkSWzevBmrVq2CxWIxOhzKJkwYiYiowDCZTLDZbChbtiy6d++OM2fOGB1SoXHx4kUMHDgQQUFBePPNN2G1Wo0OibIRE0YiIipwunbtijlz5sBqtWLDhg1sEJPDLl68iIcffhgjRozguNAFFBNGIiIqkKpUqYJixYph79696N69O06dOmV0SAVObGwshg4dCpvNhu+++w5NmjQxOiTKIUwYiYiowDKZTBgzZgxmzZqF5ORk/Pbbb7zbmE1OnTqFhx9+GEOGDGG3OYUAE0YiIirwqlativLly+PPP/9E9+7dceLECaNDyreio6MxevRoFC9eHN9++y0aN25sdEiUC5gwEhFRofF///d/mDVrFq5evYp169YhOjra6JDyDRHB1q1bMXDgQPTr1w82mw02m83osCiX8P4xEREVKlWrVgUAXL58GQMHDkT37t0xZMgQg6PKuxISErBkyRL8888/WLBgAdavXw+TyWR0WJTLmDASEVGh1KJFC6xfvx4xMTFYvXo1Tp8+jaFDh8JutxsdWp6QkpKC2NhYfP311wgLC8P8+fNhNrMwWVjxnSciokLLZDIhIiIC3bp1Q3h4OAYNGgSn04m4uDijQzPURx99hHvvvRebN2/GY489hn79+rET7kKOCSMRERV6FosF/fr1w8cff4yYmBj0798fQ4cOLVRd8Rw6dAhjx47FsWPHEBUVhXXr1uHBBx80OizKI1iSJiIiUhQvXhxfffUV9u3bB7vdjpdffhl33HEHevbsCYfDYXR42So5ORn79++HxWLB7NmzMWzYMJQvXx7ly5c3OjTKY3iHkYiIyI3q1asjIiIC48ePR3x8PN58800cPXoUX3/9NeLj440OL8uSkpJw8+ZNLFy4EPfddx9+++03VK9eHcuWLWMXOeQR7zASERF5ERgYiMcffxwAcOHCBRw+fBiLFy/G3Llzcfz4cdSoUQPFixc3OErvkpOTER0djfHjx+PixYuYMWMGevfujWHDhrHFM/nEJD52eX/lyhWEhIRgrMUMO/+4iKgASRDB6ym3GjoEBwenez71/OfpeSq8vvrqK3z++eeoVKkSRo4ciS1btqBhw4aIjIw0NBGLjo5GkSJFsHLlSqxevRpVqlTB9OnTcfnyZZQoUcKwuCjv8fX8xoSRiAo9JoyUHWJiYrBq1Sps27YNTzzxBP766y+cO3cOTZo0wQMPPACn05kj3dKcO3cOO3bsgN1uh91ux7Rp01CsWDFMmzYNycnJKFWqFPz9/bN9v1Qw+Hp+Y0maiIgoGxQrVgzDhg1zPa5duzZ2796Nw4cPw+l0omfPnkhOTkbXrl1RvXp1fPDBByhVqhSeeOIJnDhxAufPn0dQUBDatWuHjRs3upK90qVLY+3atTh79ix69OiBX375Bd9++y1sNhtWr16NGTNmoFKlSmjbti1q1aqFb775xsBXgQoqJoxEREQ5wOFwoHHjxq6GJF988YXrueTkZJQvXx5nz55FUFAQ4uPjERMTg6tXrwIADh48CD8/PwQEBKBUqVKIiIhAnTp1UKZMGQwfPhwjRoxwbWvu3Lm5e2BUKLEkTUSFHkvSRFRY+Xp+Y7c6REREROQVE0YiIiIi8ooJIxERERF5xYSRiIiIiLxiwkhEREREXjFhJCIiIiKvmDASERERkVdMGImIiIjIKyaMREREROQVE0YiIiIi8ooJIxERERF5xYSRiIiIiLxiwkhEREREXjFhJCIiIiKvmDASERERkVdMGImIiIjIKyaMREREROQVE0YiIiIi8ooJIxERERF5xYSRiIiIiLxiwkhEREREXjFhJCIiIiKvmDASERERkVdMGImIiIjIKyaMREREROQVE0YiIiIi8ooJIxERERF5xYSRiIiIiLxiwkhEREREXjFhJCIiIiKvmDASERERkVdMGImIiIjIKyaMREREROQVE0YiIiIi8ooJIxERERF5xYSRiIiIiLxiwkhEREREXjFhJCIiIiKvmDASERERkVdMGImIiIjIKyaMREREROQVE0YiIiIi8ooJIxERERF5xYSRiIiIiLxiwkhEREREXjFhJCIiIiKvmDASERERkVdMGImIiIjIKyaMREREROQVE0YiIiIi8ooJIxERERF5xYSRiIiIiLxiwkhEREREXjFhJCIiIiKvmDASERERkVdMGImIiIjIKyaMREREROQVE0YiIiIi8ooJIxERERF5xYSRiIiIiLxiwkhEREREXjFhJCIiIiKvmDASERERkVdMGImIiIjIKyaMREREROQVE0YiIiIi8ooJIxERERF5xYSRiIiIiLxiwkhEREREXjFhJCIiIiKvmDASERERkVdMGImIiIjIKyaMREREROQVE0YiIiIi8ooJIxERERF55efrgiICAEj4738iooIi9bwmHs5vqfOvXLmSazEREeWG1POap/NfKp8TxqtXrwIA5jsFAJNGIip4rl69ipCQELfzAaBMmTK5HRIRUa7wdP5LZZKMUsr/OJ1OnDlzBkWKFIHJZMq2AImIjCYiuHr1KiIjI2E2p/+lDs9/RFRQZXT+S+VzwkhEREREhRMbvRARERGRV0wYiYiIiMgrJoxERERE5BUTRiIiIiLyigkjEREREXnFhJGIiIiIvGLCSERERERe/X8HkR+l2o3dBwAAAABJRU5ErkJggg==", "text/plain": [ - "
" + "
" ] }, "metadata": {}, "output_type": "display_data" - } - ], - "source": [ - "high = jnp.array([0.1, 0.1, jnp.pi])\n", - "low = jnp.array([-0.1, -0.1, -jnp.pi])\n", - "key = jax.random.split(key, 1)[0]\n", - "\n", - "gt_contact = jax.random.uniform(key, shape=(3,)) * (high - low) + low\n", - "# gt_contact = jnp.array([-0.03, -0.09, -0.51 ])\n", - "gt_contact = jnp.array([-0.03, -0.09, -0.51 + jnp.pi ])\n", - "gt_contact = jnp.array([-0.03, 0.04,+ jnp.pi ])\n", - "observation = render_image(gt_contact)\n", - "get_depth_image(observation[...,2])\n", - "\n", - "contact_param_grid = gt_contact + contact_param_deltas\n", - "\n", - "weights = jnp.concatenate([\n", - " sweep_scorer(observation, cp, variance, outlier_prob, outlier_volume)\n", - " for cp in jnp.array_split(contact_param_grid, 100)\n", - "],axis=0)\n", - "\n", - "key2 = jax.random.PRNGKey(0)\n", - "sampled_indices = jax.random.categorical(key2, weights.reshape(-1), shape=(1000,))\n", - "sampled_indices = jnp.unravel_index(sampled_indices, weights.shape)[0]\n", - "sampled_params = contact_param_grid[sampled_indices]\n", - "actual_params = gt_contact\n", - "\n", - "fig = plt.figure(constrained_layout=True)\n", - "widths = [1, 1]\n", - "heights = [2]\n", - "spec = fig.add_gridspec(ncols=2, nrows=1, width_ratios=widths,\n", - " height_ratios=heights)\n", - "\n", - "ax = fig.add_subplot(spec[0, 0])\n", - "ax.imshow(jnp.array(get_depth_image(observation[...,2])))\n", - "ax.get_xaxis().set_visible(False)\n", - "ax.get_yaxis().set_visible(False)\n", - "ax.set_title(f\"Observation (params {gt_contact[0]:0.2f} {gt_contact[1]:0.2f} {gt_contact[2]:0.2f})\")\n", - "\n", - "\n", - "ax = fig.add_subplot(spec[0, 1])\n", - "ax.set_aspect(1.0)\n", - "circ = plt.Circle((0, 0), radius=1, edgecolor='black', facecolor='None', linestyle=\"--\", linewidth=0.5)\n", - "ax.add_patch(circ)\n", - "ax.set_xlim(-2.0, 2.0)\n", - "ax.set_ylim(-2.0, 2.0)\n", - "ax.get_xaxis().set_visible(False)\n", - "ax.get_yaxis().set_visible(False)\n", - "ax.scatter(-jnp.sin(sampled_params[:,2]),-jnp.cos(sampled_params[:,2]),label=\"Posterior Samples\", alpha=0.5, s=15)\n", - "ax.scatter(-jnp.sin(actual_params[2]),-jnp.cos(actual_params[2]), color=(1.0, 0.0, 0.0),label=\"Actual\", alpha=0.9, s=10)\n", - "ax.set_title(\"Posterior on Orientation (top view)\")\n", - "ax.legend(fontsize=7)\n", - "# plt.savefig(f'{experiment_iteration:05d}.png')\n", - "# plt.clf()\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 279, - "id": "23b381fb-7def-4154-8e39-75a80515988e", - "metadata": {}, - "outputs": [ + }, { - "name": "stdout", - "output_type": "stream", - "text": [ - "[-0.033 0.04 3.3832536] [-0.03 0.04 3.1415927]\n" - ] - } - ], - "source": [ - "print(sampled_params[0], gt_contact)" - ] + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "for experiment_iteration in tqdm(range(50)):\n", + " high = jnp.array([0.1, 0.1, jnp.pi])\n", + " low = jnp.array([-0.1, -0.1, -jnp.pi])\n", + " key = jax.random.split(key, 1)[0]\n", + " \n", + " gt_contact = jax.random.uniform(key, shape=(3,)) * (high - low) + low\n", + " # gt_contact = gt_contact.at[2].set(jnp.pi)\n", + " # gt_contact = jnp.array([-0.03, -0.09, -0.51 ])\n", + " # gt_contact = jnp.array([-0.03, -0.09, -0.51 + jnp.pi ])\n", + " observation = render_image(gt_contact)\n", + " get_depth_image(observation[...,2])\n", + " \n", + " contact_param_grid = gt_contact + contact_param_deltas\n", + " \n", + " weights = jnp.concatenate([\n", + " sweep_scorer(observation, cp, variance, outlier_prob, outlier_volume)\n", + " for cp in jnp.array_split(contact_param_grid, 100)\n", + " ],axis=0)\n", + " \n", + " key2 = jax.random.PRNGKey(0)\n", + " sampled_indices = jax.random.categorical(key2, weights.reshape(-1), shape=(1000,))\n", + " sampled_indices = jnp.unravel_index(sampled_indices, weights.shape)[0]\n", + " sampled_params = contact_param_grid[sampled_indices]\n", + " actual_params = gt_contact\n", + " \n", + " fig = plt.figure(constrained_layout=True)\n", + " widths = [1, 1]\n", + " heights = [2]\n", + " spec = fig.add_gridspec(ncols=2, nrows=1, width_ratios=widths,\n", + " height_ratios=heights)\n", + " \n", + " ax = fig.add_subplot(spec[0, 0])\n", + " ax.imshow(jnp.array(get_depth_image(observation[...,2])))\n", + " ax.get_xaxis().set_visible(False)\n", + " ax.get_yaxis().set_visible(False)\n", + " ax.set_title(f\"Observation (params {gt_contact[0]:0.2f} {gt_contact[1]:0.2f} {gt_contact[2]:0.2f})\")\n", + " \n", + " \n", + " ax = fig.add_subplot(spec[0, 1])\n", + " ax.set_aspect(1.0)\n", + " circ = plt.Circle((0, 0), radius=1, edgecolor='black', facecolor='None', linestyle=\"--\", linewidth=0.5)\n", + " ax.add_patch(circ)\n", + " ax.set_xlim(-2.0, 2.0)\n", + " ax.set_ylim(-2.0, 2.0)\n", + " ax.get_xaxis().set_visible(False)\n", + " ax.get_yaxis().set_visible(False)\n", + " ax.scatter(-jnp.sin(sampled_params[:,2]),-jnp.cos(sampled_params[:,2]),label=\"Posterior Samples\", alpha=0.5, s=15)\n", + " ax.scatter(-jnp.sin(actual_params[2]),-jnp.cos(actual_params[2]), color=(1.0, 0.0, 0.0),label=\"Actual\", alpha=0.9, s=10)\n", + " ax.set_title(\"Posterior on Orientation (top view)\")\n", + " ax.legend(fontsize=7)\n", + " # plt.show()\n", + " plt.savefig(f'{experiment_iteration:05d}.png')\n", + " plt.clf()" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "49c9bee1-c81d-43a9-b720-244b9c16c892", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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flsA2NXImX8N2tby3rlzx+6XTWbOnz8vAGTBggXp3mvVqpUAkM8++8wyLTExUUJDQ6V06dKWE7zS/TcfIG5ubuluZcjpOnx9fSUmJsYy/d1337WcQG2bifr27SsGg8Hya3L9+vUZXpRz66effsq0hr1nz57i5+eX5fJvvvmmODg4ZPier6+v9OnTJ9306tWrW35FlypVSqZMmZLtfUb79+8XALJq1ap0702cOFEApPvFbcucRF25ciXdew0bNpRnnnnGbtrbb78tFStWtKzzaZPHp/2cRUSaNm0qn3/+uWzYsEEWL14swcHB2V6clCSP5lrijBLb3DJfdLdv3y5RUVFy9epV+eGHH8Tb21ucnJzk2rVris8RSv7mszo3tWnTRurUqWP392EymaRp06ZStWrVdDE3b948XW1R2uTxzp07YjAYpF27dnZ/uwsXLhQA8s0331immc9D5oQ5O+bzk22Lw9GjR0Wr1cqAAQMs08znXNvzi4hIt27dxNvbO8tt/Prrr5akJCtubm52SU1W+5I2eczpNcxgMMj58+ft9jntuT2rv+dHjx6lm9a+fXu7a51I5s3WaZPHpKQkKV26tAQHB9vV9Jtrz99//33LNHMi98EHH9its169etKgQYN020orKCjILoEyy2x/c3N9ta1pjI2NFX9/f6lXr16WcSnNITJKHpUed2+++aZdjeL48eOlZcuWUrp0aUsr4d27d0Wj0djVUJpVq1ZNXnjhhSz342kp7m0dHx8PAHB1dc1yPvP7cXFxdtPffPNNu9ejR48GAMuQGB4eHgCADRs2wGQyZbjun376CTVr1kSNGjUQHR1t+ffcc88BAHbs2GE3f6tWrVCrVi27ac899xx8fHywdu1ay7T79+/jX//6F3r37m2Z5uDgAIPBAODJcAH37t1DSkoKwsLCcOjQoSw/g8yY93X8+PF20ydMmAAA2Lx5s930WrVqoUWLFpbXvr6+qF69Oi5evJjldsw9Aj09PTN8X6fTYfjw4ZbXBoMBw4cPx507d3Dw4EEAOd//7t27w9fX125aTtfRs2dPuLu7W143btwYAPDqq69Cp9PZTU9KSsL169cBWP92Nm3ahOTk5Cw+GWUSEhIAAEajMd17jo6OlvezWt6830qXX758ObZs2YKvvvoKNWvWREJCAlJTU58qTtt5crO87bJnz57FF198gTlz5mQ4f2487ecMAHv27MHYsWPRpUsXjBgxAgcPHkRwcDDee+89Rctnxnzs5McQY23btoWvry/Kli2LPn36oFSpUli/fj0CAwMVnyOe5m/+3r17+Pe//41evXohPj7ech69e/cu2rdvj3PnzlmOLbNhw4bBwcEhy/Vu374dSUlJGDduHLRa66Vl2LBhcHNzS3d+MxqNeO2117KN9+bNmzhy5AgGDRoELy8vy/S6devi+eefz3BYpREjRti9btGiBe7evZvuumQrJ9e4tOtRui85vYa1bdsWlStXtryuW7cu3Nzcsr0GmDk5OVnKsbGxiI6ORqtWrXDx4kXExsYqWoetAwcO4M6dO3jjjTcs5xgA6NSpE2rUqJHuOwYy/i6UxH/37t1Mr2EZyen1NSAgAN26dbO8dnNzw4ABA3D48GHcunUr0+0ozSHSyslx16JFC9y+fRtnzpwBAOzevRstW7ZEixYtsHv3bgDAX3/9BRGxyxHMPD098314RMXJo/mAMh9gmcnsAKxatard68qVK0Or1VqGy+jduzeaNWuGoUOHokyZMujTpw9+/PFHu0Ty3LlzOHHiBHx9fe3+VatWDQBw584du21UrFgxXXw6nQ7du3fHhg0bkJiYCABYt24dkpOT033xK1euRN26deHo6Ahvb2/4+vpi8+bNuTroAODy5cvQarWoUqWK3XQ/Pz94eHjg8uXLdtPLlSuXbh2enp64f/++ou2JSIbTAwIC4OLiYjfN/BnaDl+Sk/3P6LPO6TrS7q85kSxbtmyG082fQ6tWrdC9e3fMmDEDPj4+6Nq1K5YvX275fjMTGxuLW7duWf7du3cPgPWEm9Hyjx8/tjshZ8TJyQlJSUkZvpfZ8k2aNEH79u0xcuRIbN26Fd9++y3efffdbLeTVZy28+Rmedtlx44di6ZNm6J79+5ZxpSR/PqcM2IwGDBq1CjExMRYfgjlhvnYyY9xWhctWoR//etf2LFjB06ePImLFy+iffv2AJSfI3L7Nw8A58+fh4hg6tSp6c6l06ZNA6DsXJqWObbq1avbTTcYDKhUqVK681tgYGCmP7KUrBcAatasiejoaDx8+NBuetpziTkJyercmZNrXNrrm9J9yek17GmvAXv27EHbtm3h4uICDw8P+Pr64r333gOAXF3HsvouatSoke47dnR0TFepkBfXsMxiy8n1tUqVKumO74yug2nlJIewlZPjzpwQ7t69Gw8fPsThw4fRokULtGzZ0pI87t69G25ubggJCUm3LRHJ9zGmddnP8oS7uzv8/f1x7NixLOc7duwYAgMD4ebmluV8aXfMyckJu3btwo4dO7B582Zs2bIFa9euxXPPPYdt27bBwcEBJpMJderUwbx58zJcZ9okI7OLT58+fRAeHo4//vgDL730En788UfUqFHD7kv49ttvMWjQILz00kuYOHEiSpcuDQcHB3z88ce4cOFClvuWHaVfama/9LM7oLy9vQFkfaLMTk73P6PPOqfryGx/s/scNBoNfv75Z/zzzz/YuHEjtm7disGDB+Ozzz7DP//8g1KlSmW4/NixY7Fy5UrL61atWmHnzp3w9/cH8KTGI62bN28iICAgw/WZ+fv7IzU1FXfu3EHp0qUt05OSknD37t1sl/f09MRzzz2H7777DnPnzs1yO1nF6eXllWUtoe3yaY+dmzdvolGjRgCAf//739iyZQvWrVtnd1JNSUlBQkICIiMj4eXllekxn1+fc2bM+2JOUnPDfOz4+Pjkeh2ZadSoEcLCwrKcJ7tzRG7/5gFYfpC//fbblqQ1rbQX4Nwk8tnJj3Wa5ebcWbNmTQDI8hp3+fJlxMXFpWvRUrovOb2G5fYaAAAXLlxAmzZtUKNGDcybNw9ly5aFwWDA77//jvnz52fawpeXsqutzoq3t3eurmEF8WAOJTlEWjk57gICAlCxYkXs2rULFSpUgIigSZMm8PX1xdixY3H58mXs3r0bTZs2tavlN7t//366Cru8pjh5BIAXX3wRS5cuxV9//YXmzZune3/37t2IjIy0axI1O3funN2v1/Pnz8NkMqFChQqWaVqtFm3atEGbNm0wb948fPTRR5g8eTJ27Nhhqb4/evQo2rRp81R/IC1btoS/vz/Wrl2L5s2b49///jcmT55sN8/PP/+MSpUqYd26dXbbMv9CMMtJHOXLl4fJZMK5c+csJyoAuH37NmJiYlC+fPlc7pG9cuXKwcnJCZcuXcrw/Rs3buDhw4d2tY9nz54FAMv3oXT/s5IX68iJZ555Bs888wxmzZqF77//Hv369cMPP/yAoUOHZjj/pEmT8Oqrr1pem2sngoODodPpcODAAbvR+pOSknDkyJFsR/APDQ0F8KSJp2PHjpbpBw4cgMlksryflYSEhGxrBgIDA+Hr64sDBw6ke2/fvn3Zbsc2TnOiCDz5+7h27Rpef/11AMCVK1cAAC+//HK6dVy/fh0VK1bE/PnzMW7cuAy3k1+fc2bMTWJpazxywnzs2B6nBSGn54is/uYzOzdVqlQJAKDX69G2bds8jR14MiC7eRvAk+/z0qVLud6W7XrTOn36NHx8fNK1pORGtWrVUK1aNfz666/44osvMmy+XrVqFQDkenD8vLqG2cpsPRs3bkRiYiJ+++03uxrMtE3jWa0jLdvvwtzUbnbmzJk8u4YBT2oyM7qGZRZrTo8dc02g7frSXgczoySHSCunx12LFi2wa9cuVKxYEaGhoXB1dUVISAjc3d2xZcsWHDp0CDNmzEi3XEpKCq5evYouXbpku42nkaMnzEycOBFOTk4YPnx4upH27927hxEjRsDZ2RkTJ05Mt+yiRYvsXpuftvHCCy9Ylk/LfHEzVw336tUL169fx9KlS9PNm5CQkK7pIjNarRY9evTAxo0bsXr1aqSkpKSrbjb/YrL9hbd371783//9n918zs7OAKBotHtzIvH555/bTTf/Cu3UqZOi+LOj1+sRFhaWYVIBPPnjCg8Pt7xOSkpCeHg4fH190aBBAwDK9z8rebEOJe7fv5/ul3jav52M1KpVC23btrX8M++7u7s72rZti2+//dauCWv16tV48OABevbsaZn26NEjnD592u7+kueeew5eXl5YvHix3fYWL14MZ2dnu+85bTMV8KTJ5M8//8y2dgp4cq/ppk2bcPXqVcu0P//8E2fPnrWLMzk5GadPn7ar5atduzZq1KiBiIgIu/srFy9eDI1Ggx49elj2Z/369en++fr6IiwsDOvXr0fnzp0zjTG/PueMnqITHx+Pzz//HD4+Ppbt5MbBgwfh7u6O2rVr53oduaH0HKHkbz6zc1Pp0qXRunVrhIeHZ1jrm5OnE9lq27YtDAYDvvzyS7vYvv76a8TGxub6/Obv74/Q0FCsXLnSbl+OHz+Obdu22f1Ae1rvv/8+7t+/jxEjRqS75/jgwYP45JNPEBwcnKvbN4C8u4bZMifOab/njM6/sbGxWL58eYbrUHINCwsLQ+nSpbFkyRK7c+sff/yBU6dO5dk1DHhyK8/x48fTncMz29+cXl9v3LiB9evXW17HxcVh1apVCA0NhZ+fX5axKckh0srpcdeiRQtERkZi7dq1lmZsrVaLpk2bYt68eUhOTs7wfseTJ0/i8ePHaNq0aZbxPLWc9rD58ccfRa/Xi7+/v0yZMkW+/vprmTp1qgQEBIjBYEg3TlLaoXoWLVpkGarnlVdescw3duxYqVevnkyZMkWWLl0qs2bNksDAQAkKCrL0wE1NTZWOHTuKRqORPn36yIIFC+Tzzz+XESNGiJeXl13PQyDrwYPNw4S4urpKnTp10r3/zTffWHqJh4eHyzvvvCMeHh5Su3ZtKV++vN28tWrVEj8/P1m0aJGsWbPGMrxHVkP19OrVSxYtWmR5ndFQAhn1ZM1o3LCMzJ07V4xGY7rxymyH6hk9erQsWLDAMlSP7dAwSvffdozG3H6Gma3D3NPvp59+spuedsiT+fPnS9WqVWXSpEkSHh4uc+fOlerVq4ubm5tcvHgx288qIwcPHhSj0Wj35BNHR0dp165dhjGm7dG6aNEiy5ARS5cutQwZYR7Lz6x06dLSt29f+eSTTyQiIkImTpwoXl5e4ujoaNfzMjNXrlwRb29vqVy5snz55Zfy0UcfiaenZ7oefebPeODAgXbLb9y4UTQajTz33HMSEREhY8aMEa1WK8OGDct223kxSPjTfM7Tpk2TkJAQmTJlikRERMiMGTOkfPnyotFo5Ntvv7VbPiYmRmbOnCkzZ86UDh06CACZMGGCzJw5M8NRCYKDg+XVV199qn1LK7OhetJSco5Q+jef2bnpxIkT4unpKd7e3vLOO+9IRESEzJw5Uzp27Ch169ZVFHNWQ/W0a9dOFi5cKKNHj850qJ7atWsr/uzMQ/XUqFFD5syZIx988IH4+vqKp6en3f5m9lCKzMakzMjYsWMFeDJ02Jw5c2TZsmXyxhtviKOjY4ZPmMlqXzIaqudpr2Hly5e3O4737dsnAKRjx46yatUqWbNmjTx48EBOnz4tBoNB6tSpIwsXLpTZs2dL5cqVJSQkJN1n8cYbb4hGo5GZM2fKmjVrLE9XymqonsaNG8vnn38u7777rjg7O2c4VI+Li0u6+DO6LmbkwIEDAqR/WEBm+2veptLrq+1QPfPnz7cM1bNly5ZsYxPJPofIqLe10uNOROT06dOWEThs86qPP/5YAIjRaMxwNI25c+eKs7OzZcSb/JLj5FFE5NixY9K3b1/x9/cXvV4vfn5+0rdv3wzHRDP/oZw8eVJ69Oghrq6u4unpKaNGjbLr6v/nn39K165dLUloQECA9O3bV86ePWu3vqSkJPnkk0+kdu3aYjQaxdPTUxo0aCAzZsywS5SySx5NJpOULVtWAMiHH36Y4fsfffSRlC9f3nJx27RpkwwcODBd8vj3339LgwYNxGAw2F3gMhskfMaMGVKxYkXR6/VStmzZLAcxTUtp8nj79m3R6XTpBqTOaJDw8uXL2437lZP9zyp5fNp1KE0eDx06JH379pVy5cqJ0WiU0qVLy4svvigHDhzI9nPKyu7du6Vp06bi6Ogovr6+8uabb6Y7IDNLHkVEIiIipHr16mIwGKRy5coyf/78dINOT5s2TcLCwsTT01N0Op0EBARInz595NixY4rjPH78uGXsOA8PD+nXr5/cunXLbp7MkkeRJ8O+hIaGitFolKCgIJkyZYrdhT4zeZE8iuT+c962bZs8//zz4ufnJ3q9Xjw8PKRdu3YZPlYws0GzAaQ7nk+dOiVA+idbPC2lyaOSc4TSv/nMzk0iIhcuXJABAwZYPr/AwEB58cUX5eeff1YUc2YJ2cKFC6VGjRqi1+ulTJkyMnLkyEwHCc+J7du3S7NmzcTJyUnc3Nykc+fOmQ4S/jTJo8iTYXuef/55y0DOVapUkQkTJmQ4lFxOkkeRp7+GpU0eRURmzpwpgYGBlrEAzfv522+/Sd26dS2DyH/yySeWH/W2n8WtW7ekU6dO4urqKkD2g4SvXbtW6tWrJ0ajUby8vLIcJDwtpcmjyJPxDjN6WEBm+5vT6+vWrVulbt26YjQapUaNGumuNVnJLofIbJBwJcedWenSpQWwHzPYnLS2aNEiw7gaN26c5z98M6IRyUF3JipShgwZgrNnz1p6ZwFA69atER0djePHj6sYGVHhNW7cOOzatQsHDx4skJvviShjq1evxptvvokrV65YhqfKCxUqVEBwcDA2bdqUZ+ssDI4cOYL69evj0KFDiu6tfxo5uueRipZp06Zh//792LNnj9qhEBUJd+/exbJly/Dhhx8ycSRSWb9+/VCuXLl0fSYoY7Nnz0aPHj3yPXEEctjbmoqWcuXKWcb7I6LseXt748GDB2qHQUR40kGErWTK/fDDDwW2LdY8EhEREZFivOeRiIiIiBRjzSMRERERKZarex5NJhNu3LgBV1dX3lRORMWKiCA+Ph4BAQEZPvqL5z8iKq6yO/+Z5Sp5vHHjRrpncBIRFSdXr15FUFBQuuk8/xFRcZfZ+c8sV8mj+Zmfo7QaGPnLm4iKkUQRLDRJhs82Bqznv6tXr8LNza0gQyMiyldxcXEoW7Zspuc/s1wlj+amGqOGySMRFUeSaZO0ebqbmxuTRyIqlrK7JYcdZoiIiIhIMQ4STkRERHZSU1ORnJysdhiUj/R6PRwcHHK1LJNHIiIisnjw4AGuXbsGDgNdvGk0GgQFBaFUqVI5XpbJIxEREQF4UuN47do1ODs7w9fXl8NRFVMigqioKFy7dg1Vq1bNcQ0kk0ciIiICACQnJ0NE4OvrCycnJ7XDoXzk6+uLyMhIJCcn5zh5ZIcZIiIissMax+Lvab5jJo9EREREpBiTRyIiIio0dDodQkNDERwcjJ49e+LRo0c5Wn7nzp3Yt29fjrf7/vvvY/fu3TlezmzDhg0IDQ1FSEgIgoODsWHDhlyvSwkfH598XX9WmDwSERFRoeHh4YEjR47g+PHjMBgMWLJkSY6Wz03ymJqaig8++AAtWrRQvIzJZLKUk5OTMWrUKGzbtg1Hjx7FP//8g7p16+YohqKEySMRERHl2vWYBPxy8Cq+/PMcfjl4FddjEvJs3S1atMD58+cRHR2Nzp07o27dumjdujUiIyMBAD/88ANq1qyJkJAQdO3aFVevXsWSJUswe/ZshIaG4siRI4iKisLLL7+MsLAwNGnSBIcPHwYADBo0CCNHjkSjRo0we/ZsDBo0CJs2bQIAbNu2zVL7OX78eMuwRd7e3hg1ahTq1KmDs2fPWuKMj4+HiMDd3R0AUKpUKVSsWBEAsGTJEjRs2BAhISF45ZVXLONntm7dGhMmTECDBg1Qt25dHDp0CJ06dUKVKlWwcOFCAE8S4TZt2qBDhw6oXr06Jk6cmOHn9Mknn6Bhw4aoW7cu5s6dCwC4ceMGmjVrhpCQENStWxfHjh3Ls++FySMRERHlyvWYBCzddRFbT9zGxagH2HriNpbuupgnCWRKSgr++OMP1KlTB9OnT0eLFi1w7NgxjBw5EmPGjAEAzJo1C7/99huOHj2KVatWoWzZshgxYgTeeecdHDlyBKGhoRg3bhzeffddHDhwAKtWrcKIESMs27h79y727t2LyZMnW6YlJCRg2LBh+PXXX3Hs2DGcOXMG69evBwDcu3cPL7zwAv773/+iRo0almW8vLzQpk0bVKhQAQMGDLDMDwC9evXC/v37cfToUfj5+eHHH3+0vFeqVCkcPHgQvXv3Ru/evfHdd9/hwIEDmDVrlmWef/75BxEREThx4gT27t2LnTt32n1O27Ztw7Vr17Bv3z4cPnwYv//+O44fP441a9agdevWOHr0KA4dOoQqVao89XdixqF6iIiIKFf+uRCNGzEJqO7nCq1GA5MIztyKxz8XotG9QdlcrTMmJgahoaEAgJYtW2LIkCFo1KgRfv/9dwBPkrGxY8cCAJo1a4bXX38d/fr1Q48ePTJc3/bt23HixAnL6/v371vKPXr0SNfr+MyZM6hevToqVKgAAOjXrx92796Nl19+GU5OTujUqVOG21m5ciUOHz6Mbdu2YdKkSTh06BBmzpyJo0ePYurUqYiNjUVsbKzdEEhdunQBANSpUwdhYWHw8PAAALi6ulribNasGcqVK2eJ96+//kLr1q0t69i2bRs2b95suV8zPj4eZ8+eRcOGDTFgwADodDr06NEDderUyfgDzwUmj0RERJQr12Mew9ngAO3/EjCtRgNngwOuxzzO9TrN9zxmxZzwLV68GP/88w82btyIsLAw/Pe//81w/gMHDkCnS5/yODs75yi27OavV68e6tWrhzZt2mDQoEGYOXMmhgwZgs2bN6NmzZpYuHChpckdAIxGIwBAq9VayubXqampdvtqLqdNdk0mE6ZNm4aBAwemi2fPnj3YtGkT+vbti48++siSrD4tNlsTERFRrgR6OOJRUipM/7sn0CSCR0mpCPRwzNPtNG/eHN9//z0A4Oeff0ajRo0AABcvXkSTJk0wa9YsGAwG3L17F66uroiPj7cs++yzz2Lx4sWW10ePHs1yW9WrV8fZs2dx+fJlmEwmrFmzBi1btsxymQcPHmDXrl2W18eOHbPUFj58+BBlypRBUlIS1qxZk7Mdx5ME8Nq1a0hJScEvv/yC5s2b273frl07LFu2zNIrPTIyErGxsbh8+TL8/PwwfPhw9O/fP0/veWTNIxEREeXKM5V98N/rcThzKx7OBgc8SkpFgIcTmlTO22Fkpk+fjkGDBmHVqlXw8vLCihUrAABvv/02zp8/DxFBt27dEBQUhM6dO6NHjx5Yu3YtVqxYgQULFmDEiBFYtmwZkpKS0KVLF4SEhGS6LScnJ0RERKBr165ISUlBu3bt8NJLL2UZn4jg448/xuuvvw5HR0d4eXkhPDzcEntYWBhKly6NevXq5XjfGzdujKFDh+LSpUvo0qULWrVqZfd+hw4dcPLkSTzzzDMwmUzw8PDAL7/8gp07d2LOnDnQ6/Xw8PDIVeKaGY3k4snncXFxcHd3xwQHLYwchZ6IipFEEXyWakJsbCzc3NzSvW8+/2X2PlFR9vjxY1y6dAkVK1aEo6Oy2sPrMQn450I0rsc8RqCHI5pU9kGABx9tmBd27tyJhQsX4ueff87zdWf0XSs9v7HmkYiIiHIt0MMp151jqGhi8khERERUCLVu3dquZ3VhwQ4zRERERKQYk0ciIiIiUozJIxEREREpxuSRiIiIiBRj8khERESFysqVK2EwGOweJZhWZGSk3XOicyoyMhJhYWG5Xr4kY/JIRERET+fQIeDnn5/8nwfWrl2Lhg0bYv369ZnO87TJI+Uek0ciIiLKvQ8/BJ57Dhg48Mn/H374VKu7d+8ezp49i08//RRr164FANy6dcvyZJh69erh3LlzmDx5MrZv347Q0FAsW7YMK1aswNtvv21ZT1hYmOU50i+++CIaNGiA4OBgfPfdd08VHzF5JCIiotw6dAiYOxcQAdzcnvw/d+5T1UCuW7cOXbt2RdOmTXHu3DlER0djzJgx6Ny5M44ePYp//vkHAQEBmDVrFtq2bYsjR45g6NChWa5z1apVOHjwIPbu3YtZs2YhMTEx1/ERk0ciIiLKrYsXgeRkwNkZ0Gie/J+c/GR6Lq1duxa9evWCRqNBt27d8Msvv2D37t0YMmQIAMBoNMLFxSVH65w/fz5CQkLQtGlTXLlyBVeuXMl1fMQnzBAREVFuVaoE6PXAo0dPEsdHj568rlQpV6u7c+cO/vrrL/Tu3RsAkJSUhBo1aihaVqfTwWQyWV6baxd37NiBPXv2YO/evXB0dERYWBgSExOh1+tzFSOx5pGIiIhyq3594O23n9Q6xsU9+X/ixCfTc+GXX37BiBEjEBkZicjISNy4cQORkZGoU6cOvv76awBPEsqHDx/C1dUV8fHxlmXLly+Po0ePAgBOnjyJM2fOAADi4uLg7e0NR0dHHDlyxDIP5R5rHomIiCj3pkwBOnZ80lRdqVKuE0fgSZP1jBkz7KZ17twZPj4++PXXX7FgwQLo9Xr88MMPqFu3LpKTkxEaGopRo0ZhyJAh8PHxQc2aNdGgQQPUrFkTANChQwcsXrwYtWrVQu3atdGgQYOn2l0CNCIiOV0oLi4O7u7umOCghVGjyY+4iIhUkSiCz1JNiI2NhZubW7r3zee/zN4nKsoeP36MS5cuoWLFinB0dFQ7HMpHGX3XSs9vbLYmIiIiIsWYPBIRERGRYkweiYiIyE4u7mijIuZpvmN2mCEiIiIAgF6vh0ajQVRUFHx9faFhv4ZiSUQQFRUFjUaTqyGLmDwSERERAMDBwQFBQUG4du2a5dF+VDxpNBoEBQXBwcEhx8syeSQiIiKLUqVKoWrVqkhOTlY7FMpHer0+V4kjwOSRiIiI0nBwcMh1YkHFHzvMEBEREZFiTB6JiIiISDEmj0RERESkGJNHIiIiIlKMySMRERERKcbkkYiIiIgUY/JIRERERIoxeSQiIiIixZg8EhEREZFiTB6JiIiISDEmj0RERESkGJNHIiIiIlKMySMRERERKcbkkYiIiIgUY/JIRERERIoxeSQiIiIixZg8EhEREZFiTB6JiIiISDEmj0RERESkGJNHIiIiIlKMySMRERERKcbkkYiIiIgUY/JIRERERIoxeSQiIiIixZg8EhEREZFiTB6JiIiISDEmj0RERESkGJNHIiIiIlKMySMRERERKcbkkYiIiIgUY/JIRERERIoxeSQiIiIixZg8EhEREZFiTB6JiIiISDEmj0RERESkGJNHIiIiIlJMp3YARERE9ITJZEJCQgJSUlJQqlQpxMTEICUlBUajEe7u7khISICTkxM0Go3aoVIJxuSRiIiogIgI/vrrL5w9exY6nQ5dunTBkCFDkJycjNdeew06nQ7ff/899Ho95s2bh+XLl+PcuXMIDAzEW2+9hddffx2PHj1C//794eLighUrVsDf3x/vv/8+jhw5Ao1Gg9DQUHh7e6u9q1SMaUREcrpQXFwc3N3dMcFBCyN//RBRMZIogs9STYiNjYWbm1u6983nv8zeJzK7efMmEhMTcevWLXz66adITExEREQEDh06hJSUFFSqVAl16tRBSkoKDAZDrraRkJCAW7duITAwELt27cKxY8fw6NEjDBs2DGPGjEFoaCh69OiBSpUqwcHBIY/3kIobpec3Jo9ERDaYPFJu3bt3D//5z3/QtWtXdOvWDT4+PnjllVfQuHFj6HQ6ODo6Fmg88fHxOHLkCAICAvB///d/+P777+Hn54elS5damsKJbCk9v7HZmoiIKJfOnz8PjUaDPXv24Pfff8cLL7wAANiwYYPKkQGurq5o0aIFAKBy5cp49dVXcefOHWg0GvTv3x/JyckYPXo0WrduDa2W/WdJOdY8EhHZYM0jZScqKgqurq546aWXUKlSJYwYMQJ169ZVO6wci4+PR1xcHPbt24fw8HC0bt0a48ePz3UTOhV9rHkkIiLKQwcOHMDs2bPh5uaGZcuW4Y8//ijSvZ5dXV3h6uqKbt26oUuXLti9ezcAYNiwYRg4cCCaNWtWpPeP8g+TRyIiokxER0fjm2++gaenJ9q0aYPFixfD19dX7bDynIODA1q3bg0AmDJlCiIiIhAbG4uKFSuibNmycHV1VTdAKlR4kwMREVEakZGRSEhIwEcffYTatWtj8ODBqFSpUrFMHNMqX748Zs2ahU6dOuHq1avo06cPpk2bpnZYVIiw5pGIiOh/YmNj8f777+PmzZv48ssvMW/ePLVDUlX79u3Rvn173Lx5EwcPHsSmTZswfvx41kSWcKx5JCKiEi8+Ph4LFy6ETqdDnz598OOPP8LPz0/tsAoNf39/1K9fH2FhYejduzcePXoEk8mkdlikEiaPRERUov3nP//Byy+/jEqVKsHZ2RlNmjRRO6RCSaPRoFOnTti8eTM0Gg3at2+PVatWITU1Ve3QqIAxeSQiohJp3759mDFjBho2bIitW7eiY8eO7F2sgEajgZOTEzZt2oT79+/j6NGjePDggdphUQHiPY9ERFTirF69Gn/++SfmzZsHZ2dntcMpkoxGI8aOHQsRQb9+/RAWFoaxY8fyMYglAGseiYioxNi7dy/mzZuHXr16YcWKFfDy8lI7pCJPo9Hgu+++g5ubG3bv3o3Hjx+rHRLlM9Y8EhFRiRAREYG///4b8+bN43Od85hGo8HQoUMBAEOGDEFwcDDGjBnDWshiijWPRERUrF24cAHLli1Dv379WNtYAJYtWwZXV1f8/vvvyMUTkKkIYM0jFVqtAqwnnUdJ1vLtR9Z5kmw6+T1Ktd7onphmBIlEU8Y3wes01vUabX5KOdjM7qq3zlNKb53umObo8XC0LvSfG7zpnqgw2LlzJz766CN88803cHFxUTucEsG2FnLgwIF46623EBoaqm5QlKdY80hERMWOiODYsWMIDAzEr7/+iqCgILVDKpHmzZuHqVOn4ujRo2qHQnmIySMRERUriYmJGD58OLZs2YKqVauyN7WKvL29sW7dOlSrVg2LFi3iwOLFBJutqUC4JXeye/3Wn1HWF9uvW4r3jt6zlO/eSbSWY2wHobU2I8clWac6JFunO6TYNxvbNk9nxrap2tnBOr+Tzf3ebgZr2cvFfhuebtYZ36xpndGjkvUxXk7N/C3l489bD7/DPo6W8hnj39nGSkQZM5lMOHDgADp37ozOnTurHQ4B0Ov1ln99+/bF119/jVKlSqkdFj0FJo9ERFQsXLp0CePGjcP69euh1bJhrbB5/fXXLfc+xsTEwMPDQ9V4KPd4dBERUZEXExODoUOHYuHChUwcC7FGjRohKioK3bt3x+3bt9UOh3KJNY9UIOL0m+1ez7dpxl7gs8xSdm1b2lL2uO1hKTvFWv9UdQ+sTdiaeOtgtJpEmzbs5GT7AGyevSrJSciQ1trsrLEdm8zR2qQMvTUOcbaZDiC1lPW9BC/rfT1xPtbHdsWUvmUpL3EfYCmzqZoo906ePAlXV1f89ttv7FFdBFSsWBELFizA5MmTsWzZsuwXoEKHP8+IiKjIOnPmDMaMGQOj0cjEsQipVasWli5dih9++IE1kEUQk0ciIiqyNm3ahNWrV6N06dLZz0yFikajQUhICPr164fo6Gi1w6EcYLM1qcJH4izlilW3WsoXfWpYynF+AZayS3QZS7nUfTdL2emBtelY99g6HIcu0b4ntNamJ7YmOZOhIrTWZVL1NmWbwb+TnK3N3wmlrL3BAeCR+31L+YGX9URo8r5mKdfyOWQp/13qYMZxEFG2rl27hqVLl2LGjBlqh0JPoWbNmpg3bx4uXLgAHx8ftcMhhVjzSERERcqjR48wePBg9O/fX+1QKA/UrVsXNWrUwMCBAzkOZBHB5JGIiIoMEUFiYiJmzpyJKlWqqB0O5RF3d3e0atUKU6dOVTsUUoDN1qQKB7F9prS1+dfBIcVSTtFYm4hT9dbe08mO1rIuxaaHdKr1wdPadM+ytr7WZDKMh9iMEi42s6TaPNs6VW+yKdsOXA6k2MQoOpsYddb9c9E+AhHl3ieffIJ69eqhffv2aodCeWzw4ME4dOgQkpKSYDAYsl+AVMOaRyIiKhI2bdqECxcuoF27dmqHQvmkfv36GDlyJA4e5D3hhRmTRyIiKvQePnyIOnXqYOHChdBo0rYsUHEyd+5cTJw4Effu3ct+ZlIFm61JFY5ibdY1aqzNulqtzWDeNk2/qTZlk9ZkU864STnrZuuMLzxiMy647Xpty7rH1plcH9uPKZfkaN2Phw7WgcgNNmXbfSUiZeLi4tCtWzds3LgRRqNR7XAon3l6emLt2rXQarVITk6GXq/PfiEqUKx5JCKiQu2dd97B9OnT4ezsnP3MVCz4+vpi69at+PTTT9UOhTLA5JGIiAqthIQETJs2DS1atFA7FCpgvXr1wtGjR3Hq1Cm1Q6E02GxNqtCLtYnZUWtt1nXQ2jyTWmedbttsbdvzOkVv7ZGnS3awmSftWGHW30kaBT+ZbJuwHZKtzdxOF6yDm5tuXLVbxjHmpqUckJxgKV9dbY23FHtbEykWGxuLnj174o8//lA7FFKBRqNBREQEdDodUlJSoNMxZSksWPNIRESF0qRJkzB16lQ4ODhkPzMVSx4eHmy+LoSYPBIRUaGTkpKCSZMmsbma8PLLL+Pw4cM4ceKE2qHQ/7AOmFThmGptVjY6WHsg6216JsPBpoe13jrddjDuVL3NoOJ62wHD0/SotmnGtu1tbdsrO7Oe28mO1m3E+Ft/b/ksvmK3icRr+y1lMVn3ye8FL0vZ8Z8kEFHWYmNj8eqrr+K3335TOxQqBDQaDZYsWQKj0cjm60KCNY9ERFSozJo1C+PGjeN4jmTh7e2NrVu3YunSpWqHQmDySEREhcxLL72ENm3aqB0GFTJdu3bFzz//jIcPH6odSonH5JGIiAqN9957D7Vq1VI7DCqEdDod5s6di+Tk5OxnpnzFGwdIFXqT9f5CR53NPY82w/ZoHKz3GsLmqTK2w/bY3v/ooNfZzJ6muSvJej+k7S+mVIeMnySTaki1mW7ddorNPZaR79Wx24TPqz9aypJq3afUhLuW8olmtS3l5iAiW6dPn8bVq1fh4eGhdihUSNWrVw8ffvghRo4cCW9vb7XDKbFY80hERIVCZGQkpk2bpnYYVMi1aNECs2fPVjuMEo3JIxERqe7w4cPw9fVFlSpV1A6FCrlWrVrB398fIpL9zJQv2GxNqnCwOegdNdamaoNts7XGpunYZggfk+3TZnTWZmS7YXvSDtVjQ1Iz/s1kcrA2T9sP25NqU7bdtv19N1qDm6WcdO+kzfasTdjJcfbD+xDRE9OnT0d4eLjaYVARMW7cOKxZswavvPKK2qGUSKx5JCIiVd26dQu1atWCn5+f2qFQEaHVarFu3TpERUWpHUqJxOSRiIhUlZSUhI8//ljtMKiIGTJkCDZs2KB2GCUSm61JFUabjtSOGmuzrkFrLTvY9La2a6rWZ1xOSbHpbZ1J0zQAaLUZ3ydj26vaZNMLO8XuKTaZN1tHbupjKfs1nmQpa1KNlrKk8gkzRLZiY2MxatQoPk2GcqxDhw548OABUlNT+fzzAsaaRyIiUs3q1asxYMAAtcOgIsj82MItW7aoHUqJw+SRiIhU8/zzz6Nr165qh0FF1GuvvYZvvvlG7TBKHDZbkyocbZutYW3KNdo1W1unJztYm4hFa9P72a7ntd5STtFn3oRhMmU/vINtz+3Melib9GmaoG3ismXb29q2TFTS7dq1C3fu3EH16tXVDoWKKB8fH4wfP17tMEoc1jwSEZEqwsPD8cwzz6gdBhVx1atXx5dffql2GCUKk0ciIipwIoLg4GAEBQWpHQoVcd7e3ti0aRMHDS9AbLYmVdiMuw2jxrbZ2lrWa61NxIk2zcWSWRO27XOuU+z/tG1ayaE1Zf+bybZXtW3ZlEkcAKDRZ9wkrXEwZjidqCS7ePEiXn/9dbXDoGJAo9Hgueeew507d1CmTBm1wykRWPNIREQFbvbs2YiPj1c7DComJk6ciMRE3lNeUJg8EhFRgTKZTLhy5QoqVKigdihUTJhMJowYMULtMEoMNluTKrRiffa0I6zNv7YDhutteltrtBk3Hds2VWtTrL2tbZ95DQBiOwC4gmZru2dmZ7I9Sftsa5sYHQzu1thtmq3ZhE30REREhNohUDGi1+vh7e2NW7du8TGXBYA1j0REVKC++OILaDSa7GckyoGpU6fCaOQP9ILA5JGIiArUli1b2Mua8lyVKlUQHh6udhglAputSRVOidZaB6NNs7XRttnapue1/XOurdNtm47tmrNNaQYJT7Y2aWf2i8n22dapmfWwtm2q1tkPEm4bo9bglmHZwdE7k60TlQyPHz9G69atodWy7oLyllarxe7duzFp0iT+feUzfrpERFRgYmNjMXLkSLXDoGKqUaNGuHHjhtphFHtMHomIqMAsW7YMJ0+eVDsMKqamTp0KLy8vtcMo9thsTarQpdo0W4tNb2ubZ1sbFDzn2mQzPVVvbZrWpG22tpFZb2vbHtmZ9bC23R7SDBJuG6OuVKA1FgeDdbo77/Oiku3IkSN466231A6DiqmzZ88iIiIC8+bNUzuUYo01j0REVGDGjx8PZ2dntcOgYqpatWo4e/as2mEUe0weiYioQERHRyMyMlLtMKgY02q1GDRokNphFHtMHomIqEAcOHAAUVFRaodBxVxQUBCuX7+udhjFGu95JFXoUqz3PBpgHeLGUWO9b9BoM1SPVmO9H1FjMySO7dA5kmpzn2Jq5vc8anJ4z6P98DzWsm0cAKC3ecKMzsXPZj6bex49ymUaF1Fxd/bsWYSFhakdBhVz586dw6VLl9C3b1+1Qym2mDwSEVGBGDNmjNohUAlQoUIF/N///Z/aYRRrbLYmIqIC0atXL6SkpGQ/I9FTaNy4Md588021wyjWWPNIqrBtttZLqqXsaPOEGaPNUD16m2FwkmyGyEnJZNge6DP/XaTNpNna9gkzJr11XZkNz+OQZqie8sOsTdWp1ofKQONoffHWj1Ms5b9LZRoiUbGUkJAAnY6XHcp/06dPx5w5c9QOo9hizSMRERWIF154Qe0QqAQwGAw4ffq02mEUa0weiYgo35lMJjRs2FDtMKiECA4OVjuEYo3tB6QKfZJNb2ubZmudxlo22jRh6216Xts2F6dm0tta0jxhxmRTTvueZbrWum1xyKSHtS7zZmuNq491EUdrm7TGw9dSdkw1gagkio6ORnh4OBNIKhCjR4+GiECj0WQ/M+UYax6JiCjf3bhxA/7+/mqHQSXExIkTERcXp3YYxRaTRyIiyncVK1bE0KFD1Q6DSghfX18OSJ+P2GxNqjA8tpYdTdbm4lIOCdbpNk3VBttma5vBuDU2ZdumZtFlPkg4tBk3HYtNk7ltEzZsmrl9jzW2lMucdrFfbUC8dXm99dB67oNXLGX9g8zDIirOLl26hLt376J8+fJqh0IlQM+ePeHt7a12GMUWax6JiCjfXblyBRcvXlQ7DCohUlNTkZycnP2MlCtMHomIKN9ptVo4OzurHQaVENu3b+fzrfMRm61JFY6xYinrTdayEdZfira9rQ2ZDBiebPN8aZNtU7POZmBvAGJbtmkmt2PbnG27Lpvm8Ki6ey3lhGei7RYv43TTUq5ovGwp2+0TH65BJdSLL76odghUgmi1WphMHN0ivzB5JCKifLd582ZERUVh0KBBaodCJcCECRPg6OiodhjFFputiYgo32k0Gjx+/Dj7GYnywIoVK3Dt2jW1wyi2WPNIqpjecZ+l3DamnqXsYrReXGyfc+3i8MhSfqB1tZQdbJqwU22emZtlY0Umg4Rn1lSt1dk0nxuscTin6TrtbBNjKY2117irWMv+97LoBU5UjJUrV441QVRgIiMjkZLC+4TyC5NHIiLKdxUqVIBer1c7DCohypQpA3d3d7XDKLbYbE1ERPnu7t27WLBggdphUAnx2muvoXTp0mqHUWyx5pFUt93jsKXc8FGYpXxPb22ejjW5WcoPddbhPpJNBktZxNoknHZ0L7HpSS2mjH8zaWzmsR18XK+3Nls76x9ayq4666DgAODtcN9SrqS1DhFxUb/bUg7PcMtExZ+fnx9u3ryZ/YxEeWDw4MHYuHGj2mEUW6x5JCKifGc0GjF58mS1wyCiPMDkkYiICsTu3buzn4koD/A56vmLzdZUqOx3PmDzylquYTPVtpyZzXeX2L1+nOpkKZtseltrbXpYO9g821prU+7iM0zBFu3dz34WohLnzz//xJgxY6DRaNQOhYqxmJgYuLq6Zj8j5RprHomIqEAEBgYiJiZG7TComDt//jxrufMZax6JiKhALF68GCKS/YxET+H69esICAhQO4xijckjFUudvEeoHQIRpbFu3To8fPgQ/fv3VzsUKsY6dOjAAcLzGZutiYioQNSuXRsHDx5UOwwq5iZNmgSj0ah2GMUak0ciIioQVatWRe3atdUOg4q58+fPQ6djw2p+YvJIREQFQqvVonr16khNTc1+ZqJcSEhIQMuWLdUOo9hj8khERAVmw4YNOHv2rNphUDEVFxeHESN4z3t+Y/JIREQFpkGDBrzvkfJNeHg4Tp06pXYYxR6TRyIiKjCdO3dGx44d1Q6DiqmjR48iJCRE7TCKPSaPRERUYFxdXTF79my1w6BiasKECXBycsp+RnoqTB6JiKhARUdH4+rVq2qHQcXMwYMHkZCQoHYYJQKTRyIiKlB9+vTBhQsX1A6Dipm1a9fC29tb7TBKBCaPRERUoNq1a4fSpUurHQYVMzExMbzfsYAweSQiogI3ZcoUxMfHqx0GFRMPHjzAl19+CY1Go3YoJQKTRyIiKnDt27fHtm3b1A6DioklS5Zg165daodRYjB5JCKiAterVy80btxY7TComNi5cydatWqldhglBpNHIiIqcJ6envj666/x+PFjtUOhYuCtt96C0WhUO4wSg8kjERGpIigoCD/99JPaYVARt3z5cgQHB6sdRonC5JGIiFTRt29fXLt2Te0wqAhLTk7Gd999x977BYzJIxERqcLZ2RkDBw5EZGSk2qFQEXXq1Cn06dOHvawLGJNHIiJSTXx8PD766CO1w6AiSqfTYejQoWqHUeIweSQiItVUr14dt2/fRkxMjNqhUBFz+vRpfPHFF2qHUSIxeSQiIlWtXLkS7u7uaodBRczixYsxcuRItcMokZg8EhGRqtzd3dGzZ08kJyerHQoVESKC8ePHIzQ0VO1QSiQmj0REpCqNRoMXXngBX3/9tdqhUBExZcoUjhGqIiaPRESkuoEDB6Js2bJqh0FFwPXr13Hy5ElUr15d7VBKLCaPRESkOp1Oh9DQUCxdulTtUKiQi42NxcyZM9UOo0Rj8khERIVCQEAA1q1bh3v37qkdChVSZ86cwalTp/hEGZUxeSQiokJBo9Hgvffew6FDh9QOhQqp6dOnIyQkRO0wSjwmj0REVGi0aNECnp6efGwhpRMfH486deqgSpUqaodS4jF5JCKiQsVgMGDixIkQEbVDoUIiJSUFO3bswHvvvad2KAQmj0REVMjUqVMHwcHBOH78uNqhUCExd+5c3L9/X+0w6H+YPBIRUaEzefJk6PV63L59W+1QSGUJCQm4ePEiBgwYoHYo9D9MHomIqFB6/Pgxxo0bx+brEiwlJQX//PMPIiIioNFo1A6H/ofJIxERFUqhoaGoUaMG9u3bp3YopJK5c+fi6tWraodBaTB5JCKiQuv9999HYGAg7ty5o3YoVMDi4uJw8uRJ9O/fX+1QKA0mj0REVGhpNBpER0dj5MiRMJlMaodDBSQhIQGnT5/GypUr2VxdCDF5JCKiQi00NBSdOnXCDz/8oHYoVABEBMOHD0dcXBwTx0JKp3YARERE2Rk8eDAePHiAnTt3onXr1mqHQ/lo7969CAsLQ9u2bdUOhTLBmkciIioSHB0dMX/+fBw8eFDtUCifbN++HQEBARgzZozaoVAWmDwSEVGRoNPpsHz5cvz8889qh0L54OTJk5g3bx7KlCmjdiiUDSaPRERUZHh5eeHjjz/GkiVLkJiYqHY4lId27NiB5cuXw2g0qh0KZYPJIxERFTlly5bFsGHDkJqaqnYo9JQePXqEyZMn44033mCtYxHBDjNERFTkdOrUCQkJCbhz5w78/PzYK7eIevz4Mfr164fRo0fzOyxCWPNIRERFUo8ePXD//n2MHj2ajzAsgpKTk5GcnIyJEyfiueeeUzscygEmj0REVGTVqlULtWvXxsSJE9UOhXIgMTER/fr1w5kzZ9C0aVO1w6EcYrM1EREVaSNHjsStW7dw/Phx1KxZEw4ODmqHRNmYNGkSBg0ahLCwMLVDoVxgzSMRERV5fn5+OHbsGAYPHoykpCS1w6FMxMXFYd26dfjss8/QsWNHtcOhXGLySERExcIrr7yC7t27Y+vWrbwHshA6f/48unXrBn9/f+h0bPgsypg8EhFRsdGlSxe8+OKLGDhwII4cOaJ2OPQ/0dHRuHv3LlauXIkmTZqoHQ49JSaPRERUrGg0GsybNw9Tp07FsWPH1A6nRBMRLFiwAO+99x4aN26MoKAgtUOiPMDkkYiIih0fHx+sW7cOVatWxaJFi2AymdQOqUTav38/Hjx4gPDwcLVDoTzE5JGIiIolvV4PJycn6HQ6vPLKK4iNjVU7pBLjypUrGDBgAOrVq4d3332XA4AXM0weiYioWBs+fDgmTpwInU6H7du3qx1OsXf69GkMHz4cU6ZMgV6vVzscygfs7kRERMVegwYNkJSUhD///BOrV6/G559/Dk9PT7XDKtK+33sFy3ZfQPSDJPiUMuDl2h448VsEFi5ciE2bNnG8zWKMySMREZUIBoMBH3/8Mfbt2wcA2LNnD5o1a6ZyVEVTp0FfoFzMLTh5+CHOrwriHqdg7r9jMe6F15g0lgBstiYiohKlUaNGcHV1xcaNGzFw4EDcvXtX7ZCKhC3Hb6HCO5sxp2V/rPlhMj7bPB9rfpiMN/f88GQGBz1+O/tQ3SCpQDB5JCKiEken02H27NkYNWoUEhIS8NNPPyE+Pl7tsAqtLcdvYcS3B1H71nkM37cegCDe6AyIYPj+9ah96zwAIPoBn+5TEjB5JCKiEqthw4YICgqCk5MTunXrho0bN6odUqG0fM9FAEC5mFvQpaYgQWcENBok6I3QpaagXMwtAIBPKYOaYVIB4T2PRERU4r344ot44YUXEBMTgyVLlsDFxQWvvPIK79/7n+v3EwAAVzzKIMVBB6eURCTojHBKSUSKgw5XPPwAAMNbVlYzTCogrHkkIiIC4ODgAG9vb7z22mu4f/8+JkyYgISEBCQkJKgdmmpMJhO+/PJLRF0+AwA44VcV4Y26AdDANfERAA2WNHoZJ/yqAAB6NyqnXrBUYFjzSEREZMNoNGLMmDEAnoxZOG7cOAQHB2Py5MklZnifI0eOICIiAnPmzEHNmjUxv1UNvLHmyaMeFzXtg52VwlAu5hauePhZEsfI2Z3UDJkKEJNHIiKiTNSoUQNbtmzB/v374ejoiLFjx6JNmzbo1KlTsWvSfvz4MSIjI3Hz5k38+uuvGDNmDFxcXPD8888DAJY46DHi24MAgBN+VZg0lmAaEZGcLhQXFwd3d3dMcNDCyEcOEVExkiiCz1JNiI2NhZubW7r3zee/zN6n4u3evXtYsWIF3Nzc0KhRI9y9exfNmzcvsk9SSUhIgF6vx8yZM7F3714MGzYM3bt3VzssUonS8xuTRyIiG0weSanLly/j+++/x19//YUff/wRf/31Fxo3bgwPDw+1Q8tSSkoKzp07h2nTpuHx48f46quvUKpUqUIfN+U/pec3NlsTERHlQvny5fHuu+9aXt+8eRPDhg3Ds88+i/bt2+PcuXNo0KABfH19VYtRRHD9+nUEBATg888/x/bt2/Hss89i+PDhCA8PLzH3cFLeYs0jEZEN1jxSXrhy5Qp+/fVXHDx4EB988AFWrVoFjUaDFi1aoGXLlhARaLV5O+CJiODatWs4fPgwAgICcO3aNURERCAwMBDz5s3DzZs3UbFixSLbxE75j83WRES5wOSR8sPDhw9x5MgRREdHo0mTJhg2bBhEBMOGDYPJZMLWrVvh7++Pt956C/v27cODBw/g6+uL0NBQ7Nq1CykpKahSpQoMBgO2bduGmzdvYsSIEVi8eDEOHTqEsmXLYu7cuRg/fjzq1auH559/HpUqVVJ7t6mIYbM1ERFRIeHi4oJmzZpZXm/YsMFSTk5ORv369XHjxg0YjUY8ePAAUVFREBEkJyfj/Pnz0Ol08PPzg7u7OwIDAxEWFgYPDw9Mnz4dGptKnCVLlhToflHJxJpHIiIbrHkkopJK6fmNT5ghIiIiIsWYPBIRERGRYkweiYiIiEgxJo9EREREpBiTRyIiIiJSjMkjERERESnG5JGIiIiIFGPySERERESKMXkkIiIiIsWYPBIRERGRYkweiYiIiEgxJo9EREREpBiTRyIiIiJSjMkjERERESnG5JGIiIiIFGPySERERESKMXkkIiIiIsWYPBIRERGRYkweiYiIiEgxJo9EREREpBiTRyIiIiJSjMkjERERESnG5JGIiIiIFGPySERERESKMXkkIiIiIsWYPBIRERGRYkweiYiIiEgxJo9EREREpBiTRyIiIiJSjMkjERERESnG5JGIiIiIFGPySERERESKMXkkIiIiIsWYPBIRERGRYkweiYiIiEgxJo9EREREpBiTRyIiIiJSjMkjERERESnG5JGIiIiIFGPySERERESKMXkkIiIiIsWYPBIRERGRYkweiYiIiEgxJo9EREREpBiTRyIiIiJSjMkjERERESnG5JGIiIiIFGPySERERESKMXkkIiIiIsWYPBIRERGRYkweiYiIiEgxJo9EREREpBiTRyIiIiJSjMkjERERESnG5JGIiIiIFGPySERERESKMXkkIiIiIsWYPBIRERGRYkweiYiIiEgxJo9EREREpBiTRyIiIiJSjMkjERERESnG5JGIiIiIFGPySERERESKMXkkIiIiIsWYPBIRERGRYkweiYiIiEgxJo9EREREpBiTRyIiIiJSjMkjERERESnG5JGIiIiIFGPySERERESKMXkkIiIiIsWYPBIRERGRYkweiYiIiEgxXW4WEhEAQOL//iciKi7M5zXJ5Pxmnh4XF1dgMRERFQTzeS2z859ZrpLH+Ph4AMBCkwBgAklExU98fDzc3d0znA4AZcuWLeiQiIgKRGbnPzONZJdeZsBkMuHGjRtwdXWFRqN5qgCJiAoTEUF8fDwCAgKg1aa/s4fnPyIqrrI7/5nlKnkkIiIiopKJHWaIiIiISDEmj0RERESkGJNHIiIiIlKMySMRERERKcbkkYiIiIgUY/JIRERERIoxeSQiIiIixf4/ZM6VuTyRMZEAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "high = jnp.array([0.1, 0.1, jnp.pi])\n", + "low = jnp.array([-0.1, -0.1, -jnp.pi])\n", + "key = jax.random.split(key, 1)[0]\n", + "\n", + "gt_contact = jax.random.uniform(key, shape=(3,)) * (high - low) + low\n", + "gt_contact = jnp.array([-0.03, -0.09, -0.51 ])\n", + "gt_contact = jnp.array([-0.05, 0.09,+ jnp.pi ])\n", + "gt_contact = jnp.array([-0.03, 0.04,-0.51 ])\n", + "# gt_contact = jnp.array([-0.03, 0.04,+jnp.pi])\n", + "observation = render_image(gt_contact)\n", + "get_depth_image(observation[...,2])\n", + "\n", + "contact_param_grid = gt_contact + contact_param_deltas\n", + "\n", + "weights = jnp.concatenate([\n", + " sweep_scorer(observation, cp, variance, outlier_prob, outlier_volume)\n", + " for cp in jnp.array_split(contact_param_grid, 100)\n", + "],axis=0)\n", + "\n", + "key2 = jax.random.PRNGKey(0)\n", + "sampled_indices = jax.random.categorical(key2, weights.reshape(-1), shape=(100,))\n", + "sampled_indices = jnp.unravel_index(sampled_indices, weights.shape)[0]\n", + "sampled_params = contact_param_grid[sampled_indices]\n", + "actual_params = gt_contact\n", + "\n", + "fig = plt.figure(constrained_layout=True)\n", + "widths = [1, 1]\n", + "heights = [2]\n", + "spec = fig.add_gridspec(ncols=2, nrows=1, width_ratios=widths,\n", + " height_ratios=heights)\n", + "\n", + "ax = fig.add_subplot(spec[0, 0])\n", + "ax.imshow(jnp.array(get_depth_image(observation[...,2])))\n", + "ax.get_xaxis().set_visible(False)\n", + "ax.get_yaxis().set_visible(False)\n", + "ax.set_title(f\"Observation (params {gt_contact[0]:0.2f} {gt_contact[1]:0.2f} {gt_contact[2]:0.2f})\")\n", + "\n", + "\n", + "ax = fig.add_subplot(spec[0, 1])\n", + "ax.set_aspect(1.0)\n", + "circ = plt.Circle((0, 0), radius=1, edgecolor='black', facecolor='None', linestyle=\"--\", linewidth=0.5)\n", + "ax.add_patch(circ)\n", + "ax.set_xlim(-2.0, 2.0)\n", + "ax.set_ylim(-2.0, 2.0)\n", + "ax.get_xaxis().set_visible(False)\n", + "ax.get_yaxis().set_visible(False)\n", + "ax.scatter(-jnp.sin(sampled_params[:,2]),-jnp.cos(sampled_params[:,2]),label=\"Posterior Samples\", alpha=0.5, s=15)\n", + "ax.scatter(-jnp.sin(actual_params[2]),-jnp.cos(actual_params[2]), color=(1.0, 0.0, 0.0),label=\"Actual\", alpha=0.9, s=10)\n", + "ax.set_title(\"Posterior on Orientation (top view)\")\n", + "ax.legend(fontsize=7)\n", + "# plt.savefig(f'{experiment_iteration:05d}.png')\n", + "# plt.clf()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 101, + "id": "e397b20d-889c-458a-be01-79cf19b509de", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['002_master_chef_can',\n", + " '003_cracker_box',\n", + " '004_sugar_box',\n", + " '005_tomato_soup_can',\n", + " '006_mustard_bottle',\n", + " '007_tuna_fish_can',\n", + " '008_pudding_box',\n", + " '009_gelatin_box',\n", + " '010_potted_meat_can',\n", + " '011_banana',\n", + " '019_pitcher_base',\n", + " '021_bleach_cleanser',\n", + " '024_bowl',\n", + " '025_mug',\n", + " '035_power_drill',\n", + " '036_wood_block',\n", + " '037_scissors',\n", + " '040_large_marker',\n", + " '051_large_clamp',\n", + " '052_extra_large_clamp',\n", + " '061_foam_brick']" + ] + }, + "execution_count": 101, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "b.utils.ycb_loader.MODEL_NAMES" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5e17f43d-833a-4984-ae79-9a1b262548f3", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9c83ae6f-7f54-4ff1-a662-947ee4320768", + "metadata": {}, + "outputs": [], + "source": [] }, { "cell_type": "code", - "execution_count": 280, + "execution_count": 140, "id": "61503053-3b57-4961-a344-914522650f0c", "metadata": {}, "outputs": [ @@ -443,8 +1039,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "-7580.012\n", - "-7537.706\n" + "39120.23\n", + "39120.23\n" ] } ],