{ "cells": [ { "cell_type": "markdown", "id": "9b8e27d0", "metadata": {}, "source": [ "# Getting Started: Executing a Dummy Experiment Run\n", "\n", "This tutorial gently guides you through your first end-to-end run with palaestrAI. Here, you will learn how an experiment run file looks like, how to execute it, and how to query the store for data. We will stay only within palaestrAI core and not import any hARL agent, or use an extended palaestrAI environment. As such, the agents will perform only random actions in a dummy environment. That might not look super exciting, but then again, its good to start with baby steps and train the mighty agents later on...!\n", "\n", "This tutorial will call the palaestrAI API directly from the notebook. The command-line interface (CLI) does exactly that under the hood, too: There is no difference in the general usage or the layout of the experiment run files. But with the Juypter notebook, we can have everything neatly in one place.\n", "\n", "So sit back and follow us through your first experiment run... Have a lot of fun!" ] }, { "cell_type": "markdown", "id": "0c5fe5e0", "metadata": {}, "source": [ "## Imports\n", "\n", "Let's start by importing necessary modules. This will be what we need for palaestrAI, namely the entrypoint, the runtime config, and the database access stuff:" ] }, { "cell_type": "code", "execution_count": 45, "id": "b182db2e", "metadata": {}, "outputs": [], "source": [ "import palaestrai # Will provide palaestrai.exectue\n", "import palaestrai.core # RuntimeConfig\n", "import palaestrai.store # store.Session for database connectivity\n", "import palaestrai.store.database_util\n", "import palaestrai.store.database_model as paldb" ] }, { "cell_type": "markdown", "id": "d7972b02", "metadata": {}, "source": [ "The typical data science analysis toolstack uses *pandas* and *matplotlib*, so let's import those, too. " ] }, { "cell_type": "code", "execution_count": 46, "id": "09cf68b7", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import pandas as pd\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "markdown", "id": "8a5bf7b6", "metadata": {}, "source": [ "*jsonpickle* we will need to inspect the reward information objects later on. Here, we also need to use the jsonpickle extension for numpy:" ] }, { "cell_type": "code", "execution_count": 47, "id": "51d1087c", "metadata": {}, "outputs": [], "source": [ "import jsonpickle\n", "import jsonpickle.ext.numpy as jsonpickle_numpy\n", "\n", "jsonpickle_numpy.register_handlers()" ] }, { "cell_type": "markdown", "id": "6a6843e7", "metadata": {}, "source": [ "There are also some of the usual suspects from Python's standard library, which we'll import here without further comment:" ] }, { "cell_type": "code", "execution_count": 48, "id": "9894c198", "metadata": {}, "outputs": [], "source": [ "import io\n", "import os\n", "import pprint\n", "import tempfile\n", "from pathlib import Path" ] }, { "cell_type": "markdown", "id": "6095bd1b", "metadata": {}, "source": [ "## Experiment Run Document\n", "\n", "Everything palaestrAI does depends on its configuration, or rather, *experiments*. When you do real design of experiments, you first create an *experiment* document, in which you define strategies for sampling your factors. Each sample is an *experiment run*, which will be executed by palaestrAI. We won't do the full DoE dance here, but rather provide an experiment run document directly.\n", "\n", "Experiments and experiment runs have **unique names** (`uid`). When they're not given, they are auto-generated, but usually the user wants to set them in order to find them in the store later on. Choosing a good name might seem hard (it isn't, any string will do); being forced to choose a *unique* name might seem an unecessary constraint. However, it isn't: Each experiment run must be repeatable, i.e., always have the same result, no matter how often it is run. A change in an experiment run definition can yield different results. Therefore, each experiment run is unique—and thus should be its name, too. We will define the experiment run name as a separate variable so that we don't have to remember it later on when we query the store:" ] }, { "cell_type": "code", "execution_count": 49, "id": "535b0ff2", "metadata": {}, "outputs": [], "source": [ "experiment_run_name = \"Tutorial Experiment Run\"" ] }, { "cell_type": "markdown", "id": "159543fc", "metadata": {}, "source": [ "Experiment (run) documents also have a **version**. It serves as a discriminator to catch semantic changes in the document. It is an additional safeguard and emits a log message, but not a stopgap. \n", "\n", "For this tutorial, we set the document's version to palaestrAI's version. That is okay here since we need to keep this documented up-to-date in any case. When experiment runs are archived, the version number (and its immutability!) become more important." ] }, { "cell_type": "code", "execution_count": 50, "id": "fbdc8cae", "metadata": {}, "outputs": [], "source": [ "experiment_run_version = \"3.4\"" ] }, { "cell_type": "markdown", "id": "3ea94d25", "metadata": {}, "source": [ "And now to the document itself. Apart from the `uid`, the `version`, and the random seed (`seed`), it provides the configuration of the experiment run. Experiment runs have *phases*, so the most important key here is the experiment `schedule`.\n", "\n", "A **schedule** defines the phases of an experiment run. A phase comprises environments, agents, simulation parameters such as the termination condition, as well as general configuration flags. Schedule configurations are cascading: Values defined in the previous phase are applied to following phases, too, unless they are explicitly overwritten.\n", "\n", "In our example, we have three phases in our schedule. The first phase trains only one agent, the second trains two in the same environment, and finally, there is a third phase as testing stage.\n", "\n", "(*Please note* that we're using an f-string here, and hence the YAML dict `{}` becomes `{{}}`.)" ] }, { "cell_type": "code", "execution_count": 51, "id": "7af1b51e", "metadata": {}, "outputs": [], "source": [ "experiment_run_document = f\"\"\"\n", "uid: \"{experiment_run_name}\"\n", "seed: 47 # Not quite Star Trek, but...\n", "version: \"{experiment_run_version}\"\n", "schedule: # The schedule for this run; it is a list\n", " - phase_0:\n", " environments: # Definition of the environments for this phase\n", " - environment:\n", " name: palaestrai.environment.dummy_environment:DummyEnvironment\n", " uid: denv\n", " params: {{ }}\n", " agents: # Definiton of agents for this phase\n", " - name: mighty_defender\n", " brain:\n", " name: palaestrai.agent.dummy_brain:DummyBrain\n", " params: {{ }}\n", " muscle:\n", " name: palaestrai.agent.dummy_muscle:DummyMuscle\n", " params: {{ }}\n", " objective:\n", " name: palaestrai.agent.dummy_objective:DummyObjective\n", " params: {{\"params\": 1}}\n", " sensors: [denv.0, denv.1, denv.2, denv.3, denv.4]\n", " actuators: [denv.0, denv.1, denv.2, denv.3, denv.4]\n", " simulation: # Definition of the simulation controller for this phase\n", " name: palaestrai.simulation:VanillaSimulationController\n", " conditions:\n", " - name: palaestrai.simulation:VanillaSimControllerTerminationCondition\n", " params: {{ }}\n", " phase_config: # Additional config for this phase\n", " mode: train\n", " worker: 1\n", " episodes: 5 \n", " - phase_1: # Name of the current phase. Can be any user-chosen name\n", " agents: # Definiton of agents for this phase\n", " - name: mighty_defender\n", " brain:\n", " name: palaestrai.agent.dummy_brain:DummyBrain\n", " params: {{ }}\n", " muscle:\n", " name: palaestrai.agent.dummy_muscle:DummyMuscle\n", " params: {{ }}\n", " objective:\n", " name: palaestrai.agent.dummy_objective:DummyObjective\n", " params: {{\"params\": 1}}\n", " sensors: [denv.0, denv.1, denv.2, denv.3, denv.4]\n", " actuators: [denv.0, denv.1, denv.2, denv.3, denv.4]\n", " - name: evil_attacker\n", " brain:\n", " name: palaestrai.agent.dummy_brain:DummyBrain\n", " params: {{ }}\n", " muscle:\n", " name: palaestrai.agent.dummy_muscle:DummyMuscle\n", " params: {{ }}\n", " objective:\n", " name: palaestrai.agent.dummy_objective:DummyObjective\n", " params: {{\"params\": 1}}\n", " sensors: [denv.5, denv.6, denv.7, denv.8, denv.9]\n", " actuators: [denv.5, denv.6, denv.7, denv.8, denv.9]\n", " simulation: # Definition of the simulation controller for this phase\n", " name: palaestrai.simulation:VanillaSimulationController\n", " conditions:\n", " - name: palaestrai.simulation:VanillaSimControllerTerminationCondition\n", " params: {{ }}\n", " phase_config: # Additional config for this phase\n", " mode: train\n", " worker: 1\n", " episodes: 2\n", " - phase_2: # Definition of the second phase. Keeps every information\n", " # from the first except for those keys that are redefined\n", " # here.\n", " phase_config: \n", " mode: test\n", " episodes: 3\n", "run_config: # Not a runTIME config\n", " condition: \n", " name: palaestrai.experiment:VanillaRunGovernorTerminationCondition\n", " params: {{ }}\n", "\"\"\"" ] }, { "cell_type": "markdown", "id": "070883b4", "metadata": {}, "source": [ "## Runtime Config\n", "\n", "With the experiment run neatly defined, there is something else that defines how palaestrAI behaves: Its runtime config. It has nothing to do with an experiment run, but defines the behavior of palaestrAI on a certain machine. This includes log levels or the URI defining how to connect to the database. Usually, one does not touch it once the framework is installed.\n", "\n", "In this case, we're playing it safe and provide some sane defaults that are only relevant for the scope of this notebook. For example, we'll resort to using SQLite in a temporary directory instead of PostgreSQL + TimescaleDB (speed is not of importance here).\n", "\n", "Let's create the database in a temporary location:" ] }, { "cell_type": "code", "execution_count": 52, "id": "2f07fabc", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "store_dir = tempfile.TemporaryDirectory()\n", "store_dir" ] }, { "cell_type": "code", "execution_count": 53, "id": "9101ad4c", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'data_path': './_outputs',\n", " 'executor_bus_port': 4747,\n", " 'logger_port': 4748,\n", " 'logging': {'filters': {'debug_filter': {'()': 'palaestrai.core.runtime_config.DebugLogFilter'}},\n", " 'formatters': {'debug': {'format': '%(asctime)s '\n", " '%(name)s[%(process)d]: '\n", " '%(levelname)s - %(message)s '\n", " '(%(module)s.%(funcName)s in '\n", " '%(filename)s:%(lineno)d)'},\n", " 'simple': {'format': '%(asctime)s '\n", " '%(name)s[%(process)d]: '\n", " '%(levelname)s - '\n", " '%(message)s'}},\n", " 'handlers': {'console': {'class': 'logging.StreamHandler',\n", " 'formatter': 'simple',\n", " 'level': 'INFO',\n", " 'stream': 'ext://sys.stdout'},\n", " 'console_debug': {'class': 'logging.StreamHandler',\n", " 'filters': ['debug_filter'],\n", " 'formatter': 'debug',\n", " 'level': 'DEBUG',\n", " 'stream': 'ext://sys.stdout'}},\n", " 'loggers': {'palaestrai.agent': {'level': 'ERROR'},\n", " 'palaestrai.agent.agent_conductor': {'level': 'ERROR'},\n", " 'palaestrai.agent.brain': {'level': 'ERROR'},\n", " 'palaestrai.agent.muscle': {'level': 'ERROR'},\n", " 'palaestrai.core': {'level': 'ERROR'},\n", " 'palaestrai.environment': {'level': 'ERROR'},\n", " 'palaestrai.experiment': {'level': 'ERROR'},\n", " 'palaestrai.simulation': {'level': 'ERROR'},\n", " 'palaestrai.store': {'level': 'ERROR'},\n", " 'palaestrai.types': {'level': 'ERROR'},\n", " 'palaestrai.util': {'level': 'ERROR'},\n", " 'palaestrai.visualization': {'level': 'ERROR'},\n", " 'sqlalchemy.engine': {'level': 'ERROR'}},\n", " 'root': {'handlers': ['console', 'console_debug'],\n", " 'level': 'ERROR'},\n", " 'version': 1},\n", " 'major_domo_client_retries': 3,\n", " 'major_domo_client_timeout': 300000,\n", " 'profile': False,\n", " 'public_bind': False,\n", " 'store_uri': 'sqlite:////tmp/tmp4ke3ntu0/palaestrai.db',\n", " 'time_series_store_uri': 'influx+localhost:8086'}\n" ] } ], "source": [ "runtime_config = palaestrai.core.RuntimeConfig()\n", "runtime_config.reset()\n", "runtime_config.load(\n", " {\n", " \"store_uri\": \"sqlite:///%s/palaestrai.db\" % store_dir.name,\n", " \"executor_bus_port\": 4747,\n", " \"logger_port\": 4748,\n", " }\n", ")\n", "pprint.pprint(runtime_config.to_dict())" ] }, { "cell_type": "markdown", "id": "de573131", "metadata": {}, "source": [ "The nice thing about the `RuntimeConfig` is that it is a singleton available everywhere in the framework. So whatever we set here pertains throughout the run." ] }, { "cell_type": "markdown", "id": "07d3398c", "metadata": {}, "source": [ "## Database Initialization\n", "\n", "Since we've opted to start fresh with a new SQLite database in a temporary directory, we will have to create and initialize it. Usually, one does this once (e.g., from the CLI with `palaestrai database-create`) and is then done with it, but in this case we do it every time we run the notebook—it is a one-shot tutorial, after all. :-)\n", "\n", "Luckily, palaestrAI has just the function we need to do it for us:" ] }, { "cell_type": "code", "execution_count": 54, "id": "6d9ad50c", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Could not create extension timescaledb and create hypertables: (sqlite3.OperationalError) near \"EXTENSION\": syntax error\n", "[SQL: CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE;]\n", "(Background on this error at: https://sqlalche.me/e/14/e3q8). Your database setup might lead to noticeable slowdowns with larger experiment runs. Please upgrade to PostgreSQL with TimescaleDB for the best performance.\n" ] } ], "source": [ "palaestrai.store.database_util.setup_database(runtime_config.store_uri)" ] }, { "cell_type": "markdown", "id": "90b4dcee", "metadata": {}, "source": [ "You will see a warning regarding the TimescaleDB extension. That is okay and just a warning. Since we're not running a big, sophisticated experiment, we can live with a bit of a performance penality." ] }, { "cell_type": "markdown", "id": "f057b6c4", "metadata": {}, "source": [ "## Experiment Run Execution\n", "\n", "Next up: Actually executing the experiment run! It just consists of one line: A call to `palaestrai.execute()`. This method can cope with three types of parameters:\n", "\n", "1. An `ExperimentRun` object. Nice in cases one has already loaded it (e.g., de-serialized it).\n", "2. A `str`. `palaestrAI.execute()` interprets this as a path to a file—one of the most common use cases.\n", "3. A `TextIO` object: Any stream that delivers text. Useful when the experiment run document is not yet deserialized, and exactly what we need.\n", "\n", "To turn a `str` into a `TextIO`, we simply wrap it into a `StringIO` object. Make it so!" ] }, { "cell_type": "code", "execution_count": 55, "id": "4f9ad2bc", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Your palaestrAI installation has version 3.5.0 but your run file uses version 3.4, which may be incompatible.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n", "10\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n", "10\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n", "10\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n", "10\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n", "10\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n", "10\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n", "10\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n", "10\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n", "10\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n", "10\n" ] } ], "source": [ "rc = palaestrai.execute(io.StringIO(experiment_run_document))" ] }, { "cell_type": "code", "execution_count": null, "id": "1183b705", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "27e7f0c3", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "id": "fb814bcc", "metadata": {}, "source": [ "The execution should yield no errors (and no warnings, too)." ] }, { "cell_type": "code", "execution_count": 56, "id": "462254bd", "metadata": {}, "outputs": [], "source": [ "assert rc[1].name == \"EXITED\"" ] }, { "cell_type": "markdown", "id": "a06a9446", "metadata": {}, "source": [ "## Querying the Store\n", "\n", "Let's get a custom session to the database first:" ] }, { "cell_type": "code", "execution_count": 57, "id": "8fe377d7", "metadata": {}, "outputs": [], "source": [ "dbh = palaestrai.store.Session()" ] }, { "cell_type": "markdown", "id": "7798b78d", "metadata": {}, "source": [ "palaestrAI has no special database access features, only nice object-relational mapper (ORM) bindings provided by SQLAlchemy. Which means that we can use all the nice magic SQLAlchemy gives us. So let's first import it:" ] }, { "cell_type": "code", "execution_count": 58, "id": "4d9c6f1e", "metadata": {}, "outputs": [], "source": [ "import sqlalchemy as sa" ] }, { "cell_type": "markdown", "id": "d90634a5", "metadata": {}, "source": [ "Do you remember the name of our experiment run? We can now use it to look it up. Therefore, we first create a query using `sqlalchemy.select`, which we then execute." ] }, { "cell_type": "code", "execution_count": 59, "id": "283c6f69", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'SELECT experiment_runs.document, experiment_runs.document_json, experiment_runs.id, experiment_runs.uid, experiment_runs.experiment_id \\nFROM experiment_runs \\nWHERE experiment_runs.uid = :uid_1'" ] }, "execution_count": 59, "metadata": {}, "output_type": "execute_result" } ], "source": [ "q = sa.select(paldb.ExperimentRun).where(\n", " paldb.ExperimentRun.uid == experiment_run_name\n", ")\n", "str(q)" ] }, { "cell_type": "markdown", "id": "e78a387c", "metadata": {}, "source": [ "palaestrAI ensures through the `uid` that each experiment run is stored only once in the database. `one()` not only retrieves only one element from the query, it also raises an exception if there's no or more than one row in the result set. Thus:" ] }, { "cell_type": "code", "execution_count": 60, "id": "9947bf58", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1, 'Tutorial Experiment Run')" ] }, "execution_count": 60, "metadata": {}, "output_type": "execute_result" } ], "source": [ "result = dbh.execute(q).one()\n", "experiment_run_record = result[paldb.ExperimentRun]\n", "experiment_run_record.id, experiment_run_record.uid" ] }, { "cell_type": "markdown", "id": "cdf8d8fb", "metadata": {}, "source": [ "…yes, that's us. \n", "\n", "No matter how often an experiment run is executed, there will be only one entry for the same UID in the table. But many more instances will exist. Here, since we ran it only once, we will also see only one experiment run instance.\n", "\n", "Through the SQLAlechemy ORM, we can access the experiment run instances directly:" ] }, { "cell_type": "code", "execution_count": 61, "id": "93c30ef4", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "experiment_run_record.experiment_run_instances" ] }, { "cell_type": "markdown", "id": "3244ab70", "metadata": {}, "source": [ "Would we run execute the run again, we'd see two entries in the list here:" ] }, { "cell_type": "code", "execution_count": 62, "id": "2966c304", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Your palaestrAI installation has version 3.5.0 but your run file uses version 3.4, which may be incompatible.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n", "10\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n", "10\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n", "10\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n", "10\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n", "10\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n", "10\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n", "10\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n", "10\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n", "10\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n", "10\n" ] } ], "source": [ "rc = palaestrai.execute(io.StringIO(experiment_run_document))\n", "assert rc[1].name == \"EXITED\"" ] }, { "cell_type": "code", "execution_count": 63, "id": "476c1570", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[,\n", " ]" ] }, "execution_count": 63, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dbh.refresh(experiment_run_record)\n", "experiment_run_record.experiment_run_instances" ] }, { "cell_type": "code", "execution_count": 64, "id": "b2ad4d0e", "metadata": {}, "outputs": [], "source": [ "assert len(experiment_run_record.experiment_run_instances) > 1" ] }, { "cell_type": "markdown", "id": "fc40f611", "metadata": {}, "source": [ "Now let's focus on the run phases. Each instance will have several of them—three, to be precise. Remember our experiment run document? We have three, so lets find them in the database:" ] }, { "cell_type": "code", "execution_count": 65, "id": "212026b0", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 65, "metadata": {}, "output_type": "execute_result" } ], "source": [ "experiment_run_record.experiment_run_instances[1]" ] }, { "cell_type": "code", "execution_count": 66, "id": "9df8d722", "metadata": {}, "outputs": [], "source": [ "assert (\n", " len(\n", " experiment_run_record.experiment_run_instances[0].experiment_run_phases\n", " )\n", " == 3\n", ")" ] }, { "cell_type": "markdown", "id": "b16ed410", "metadata": {}, "source": [ "Next up: Who did participate in this run phase? We can define participants for each run phase separately. In our experiment run document, we decided that first one agent may train on its own, then we have two agents train together, and finally a test phase for both. So that is what we want to see now.\n", "\n", "However, simply exploring the ORM is not really fun for showing it in a Jupyter notebook. Thankfully, SQLAlchemy and pandas interface nicely: We can construct a query in SQLAlchemy with our ORM and than end it over to pandas to construct a dataframe out of it:" ] }, { "cell_type": "code", "execution_count": 67, "id": "6a61e0bb", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
iduidnamemusclesconfigurationexperiment_run_phase_id
01mighty_defendermighty_defender[Tutorial Experiment Run_A:0fde7238-1e1b-4c2e-...{'name': 'mighty_defender', 'brain': {'name': ...1
12mighty_defendermighty_defender[Tutorial Experiment Run_A:814e074f-1182-41c1-...{'name': 'mighty_defender', 'brain': {'name': ...2
23evil_attackerevil_attacker[Tutorial Experiment Run_A:914d21dd-fd8b-43cf-...{'name': 'evil_attacker', 'brain': {'name': 'p...2
34mighty_defendermighty_defender[Tutorial Experiment Run_A:4bb49b68-0870-474b-...{'name': 'mighty_defender', 'brain': {'name': ...3
45evil_attackerevil_attacker[Tutorial Experiment Run_A:89555042-cabb-4077-...{'name': 'evil_attacker', 'brain': {'name': 'p...3
\n", "
" ], "text/plain": [ " id uid name \\\n", "0 1 mighty_defender mighty_defender \n", "1 2 mighty_defender mighty_defender \n", "2 3 evil_attacker evil_attacker \n", "3 4 mighty_defender mighty_defender \n", "4 5 evil_attacker evil_attacker \n", "\n", " muscles \\\n", "0 [Tutorial Experiment Run_A:0fde7238-1e1b-4c2e-... \n", "1 [Tutorial Experiment Run_A:814e074f-1182-41c1-... \n", "2 [Tutorial Experiment Run_A:914d21dd-fd8b-43cf-... \n", "3 [Tutorial Experiment Run_A:4bb49b68-0870-474b-... \n", "4 [Tutorial Experiment Run_A:89555042-cabb-4077-... \n", "\n", " configuration experiment_run_phase_id \n", "0 {'name': 'mighty_defender', 'brain': {'name': ... 1 \n", "1 {'name': 'mighty_defender', 'brain': {'name': ... 2 \n", "2 {'name': 'evil_attacker', 'brain': {'name': 'p... 2 \n", "3 {'name': 'mighty_defender', 'brain': {'name': ... 3 \n", "4 {'name': 'evil_attacker', 'brain': {'name': 'p... 3 " ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.read_sql(\n", " sa.select(paldb.Agent).where(\n", " paldb.Agent.experiment_run_phase_id.in_(\n", " phase.id\n", " for phase in experiment_run_record.experiment_run_instances[\n", " 0\n", " ].experiment_run_phases\n", " )\n", " ),\n", " dbh.bind,\n", ")" ] }, { "cell_type": "markdown", "id": "a4a1902e", "metadata": {}, "source": [ "Okay, now that we have explored many things, let's find out how good our agents were! Let us start by looking at how well the first agent trained when it was alone. Each agent gets a new ID when it enters a new experiment run phase, regardless of whether its the same agent than before or a new one. (The discriminating element is the agent's name.)\n", "\n", "We first need the ID of the first experiment run phase:" ] }, { "cell_type": "code", "execution_count": 68, "id": "da9ce13d", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 68, "metadata": {}, "output_type": "execute_result" } ], "source": [ "run_phase_id = min(\n", " phase.id\n", " for phase in experiment_run_record.experiment_run_instances[\n", " 0\n", " ].experiment_run_phases\n", ")\n", "run_phase_id" ] }, { "cell_type": "markdown", "id": "f255bd8f", "metadata": {}, "source": [ "Okay, which agent is it?" ] }, { "cell_type": "code", "execution_count": 69, "id": "71377cbb", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1, 'mighty_defender')" ] }, "execution_count": 69, "metadata": {}, "output_type": "execute_result" } ], "source": [ "agent_record = dbh.execute(\n", " sa.select(paldb.Agent).where(\n", " paldb.Agent.experiment_run_phase_id == run_phase_id\n", " )\n", ").one()[paldb.Agent]\n", "assert agent_record.name == \"mighty_defender\"\n", "agent_record.id, agent_record.name" ] }, { "cell_type": "code", "execution_count": 70, "id": "2495ce6d", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
idwalltimeagent_idsimtimessensor_readingsactuator_setpointsrewardsobjective
012023-12-13 14:04:42.2382461{'denv': {'py/object': 'palaestrai.types.simti...[][][{'py/object': 'palaestrai.agent.reward_inform...0.0
122023-12-13 14:04:42.2697781{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...1.0
232023-12-13 14:04:42.2983541{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...3.0
342023-12-13 14:04:42.3248101{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...6.0
452023-12-13 14:04:42.3540931{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...10.0
562023-12-13 14:04:42.3827571{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...15.0
672023-12-13 14:04:42.4107071{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...21.0
782023-12-13 14:04:42.4396301{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...28.0
892023-12-13 14:04:42.4695561{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...36.0
9102023-12-13 14:04:42.4977251{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...45.0
10112023-12-13 14:04:42.5310331{}[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[]45.0
11122023-12-13 14:04:42.5596941{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...45.0
12132023-12-13 14:04:42.5890401{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...46.0
13142023-12-13 14:04:42.6182501{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...48.0
14152023-12-13 14:04:42.6477491{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...51.0
15162023-12-13 14:04:42.6752421{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...55.0
16172023-12-13 14:04:42.7066401{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...60.0
17182023-12-13 14:04:42.7348831{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...66.0
18192023-12-13 14:04:42.7633091{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...73.0
19202023-12-13 14:04:42.7915861{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...81.0
20212023-12-13 14:04:42.8203771{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...90.0
21222023-12-13 14:04:42.8528971{}[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[]90.0
22232023-12-13 14:04:42.8821831{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...90.0
23242023-12-13 14:04:42.9149381{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...91.0
24252023-12-13 14:04:42.9496411{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...93.0
25262023-12-13 14:04:42.9898571{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...96.0
26272023-12-13 14:04:43.0233441{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...100.0
27282023-12-13 14:04:43.0559701{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...105.0
28292023-12-13 14:04:43.0865481{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...111.0
29302023-12-13 14:04:43.1246221{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...118.0
30312023-12-13 14:04:43.1562421{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...126.0
31322023-12-13 14:04:43.1875641{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...135.0
32332023-12-13 14:04:43.2246151{}[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[]135.0
33342023-12-13 14:04:43.2555821{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...135.0
34352023-12-13 14:04:43.2870021{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...136.0
35362023-12-13 14:04:43.3216051{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...138.0
36372023-12-13 14:04:43.3532631{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...141.0
37382023-12-13 14:04:43.3836041{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...145.0
38392023-12-13 14:04:43.4139911{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...150.0
39402023-12-13 14:04:43.4465561{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...156.0
40412023-12-13 14:04:43.4761321{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...163.0
41422023-12-13 14:04:43.5057111{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...171.0
42432023-12-13 14:04:43.5367841{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...180.0
43442023-12-13 14:04:43.5765471{}[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[]180.0
44452023-12-13 14:04:43.6076401{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...180.0
45462023-12-13 14:04:43.6387261{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...181.0
46472023-12-13 14:04:43.6717911{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...183.0
47482023-12-13 14:04:43.7046901{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...186.0
48492023-12-13 14:04:43.7397401{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...190.0
49502023-12-13 14:04:43.7746561{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...195.0
50512023-12-13 14:04:43.8215131{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...201.0
51522023-12-13 14:04:43.8570551{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...208.0
52532023-12-13 14:04:43.8938551{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...216.0
53542023-12-13 14:04:43.9303491{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...225.0
\n", "
" ], "text/plain": [ " id walltime agent_id \\\n", "0 1 2023-12-13 14:04:42.238246 1 \n", "1 2 2023-12-13 14:04:42.269778 1 \n", "2 3 2023-12-13 14:04:42.298354 1 \n", "3 4 2023-12-13 14:04:42.324810 1 \n", "4 5 2023-12-13 14:04:42.354093 1 \n", "5 6 2023-12-13 14:04:42.382757 1 \n", "6 7 2023-12-13 14:04:42.410707 1 \n", "7 8 2023-12-13 14:04:42.439630 1 \n", "8 9 2023-12-13 14:04:42.469556 1 \n", "9 10 2023-12-13 14:04:42.497725 1 \n", "10 11 2023-12-13 14:04:42.531033 1 \n", "11 12 2023-12-13 14:04:42.559694 1 \n", "12 13 2023-12-13 14:04:42.589040 1 \n", "13 14 2023-12-13 14:04:42.618250 1 \n", "14 15 2023-12-13 14:04:42.647749 1 \n", "15 16 2023-12-13 14:04:42.675242 1 \n", "16 17 2023-12-13 14:04:42.706640 1 \n", "17 18 2023-12-13 14:04:42.734883 1 \n", "18 19 2023-12-13 14:04:42.763309 1 \n", "19 20 2023-12-13 14:04:42.791586 1 \n", "20 21 2023-12-13 14:04:42.820377 1 \n", "21 22 2023-12-13 14:04:42.852897 1 \n", "22 23 2023-12-13 14:04:42.882183 1 \n", "23 24 2023-12-13 14:04:42.914938 1 \n", "24 25 2023-12-13 14:04:42.949641 1 \n", "25 26 2023-12-13 14:04:42.989857 1 \n", "26 27 2023-12-13 14:04:43.023344 1 \n", "27 28 2023-12-13 14:04:43.055970 1 \n", "28 29 2023-12-13 14:04:43.086548 1 \n", "29 30 2023-12-13 14:04:43.124622 1 \n", "30 31 2023-12-13 14:04:43.156242 1 \n", "31 32 2023-12-13 14:04:43.187564 1 \n", "32 33 2023-12-13 14:04:43.224615 1 \n", "33 34 2023-12-13 14:04:43.255582 1 \n", "34 35 2023-12-13 14:04:43.287002 1 \n", "35 36 2023-12-13 14:04:43.321605 1 \n", "36 37 2023-12-13 14:04:43.353263 1 \n", "37 38 2023-12-13 14:04:43.383604 1 \n", "38 39 2023-12-13 14:04:43.413991 1 \n", "39 40 2023-12-13 14:04:43.446556 1 \n", "40 41 2023-12-13 14:04:43.476132 1 \n", "41 42 2023-12-13 14:04:43.505711 1 \n", "42 43 2023-12-13 14:04:43.536784 1 \n", "43 44 2023-12-13 14:04:43.576547 1 \n", "44 45 2023-12-13 14:04:43.607640 1 \n", "45 46 2023-12-13 14:04:43.638726 1 \n", "46 47 2023-12-13 14:04:43.671791 1 \n", "47 48 2023-12-13 14:04:43.704690 1 \n", "48 49 2023-12-13 14:04:43.739740 1 \n", "49 50 2023-12-13 14:04:43.774656 1 \n", "50 51 2023-12-13 14:04:43.821513 1 \n", "51 52 2023-12-13 14:04:43.857055 1 \n", "52 53 2023-12-13 14:04:43.893855 1 \n", "53 54 2023-12-13 14:04:43.930349 1 \n", "\n", " simtimes \\\n", "0 {'denv': {'py/object': 'palaestrai.types.simti... \n", "1 {'denv': {'py/object': 'palaestrai.types.simti... \n", "2 {'denv': {'py/object': 'palaestrai.types.simti... \n", "3 {'denv': {'py/object': 'palaestrai.types.simti... \n", "4 {'denv': {'py/object': 'palaestrai.types.simti... \n", "5 {'denv': {'py/object': 'palaestrai.types.simti... \n", "6 {'denv': {'py/object': 'palaestrai.types.simti... \n", "7 {'denv': {'py/object': 'palaestrai.types.simti... \n", "8 {'denv': {'py/object': 'palaestrai.types.simti... \n", "9 {'denv': {'py/object': 'palaestrai.types.simti... \n", "10 {} \n", "11 {'denv': {'py/object': 'palaestrai.types.simti... \n", "12 {'denv': {'py/object': 'palaestrai.types.simti... \n", "13 {'denv': {'py/object': 'palaestrai.types.simti... \n", "14 {'denv': {'py/object': 'palaestrai.types.simti... \n", "15 {'denv': {'py/object': 'palaestrai.types.simti... \n", "16 {'denv': {'py/object': 'palaestrai.types.simti... \n", "17 {'denv': {'py/object': 'palaestrai.types.simti... \n", "18 {'denv': {'py/object': 'palaestrai.types.simti... \n", "19 {'denv': {'py/object': 'palaestrai.types.simti... \n", "20 {'denv': {'py/object': 'palaestrai.types.simti... \n", "21 {} \n", "22 {'denv': {'py/object': 'palaestrai.types.simti... \n", "23 {'denv': {'py/object': 'palaestrai.types.simti... \n", "24 {'denv': {'py/object': 'palaestrai.types.simti... \n", "25 {'denv': {'py/object': 'palaestrai.types.simti... \n", "26 {'denv': {'py/object': 'palaestrai.types.simti... \n", "27 {'denv': {'py/object': 'palaestrai.types.simti... \n", "28 {'denv': {'py/object': 'palaestrai.types.simti... \n", "29 {'denv': {'py/object': 'palaestrai.types.simti... \n", "30 {'denv': {'py/object': 'palaestrai.types.simti... \n", "31 {'denv': {'py/object': 'palaestrai.types.simti... \n", "32 {} \n", "33 {'denv': {'py/object': 'palaestrai.types.simti... \n", "34 {'denv': {'py/object': 'palaestrai.types.simti... \n", "35 {'denv': {'py/object': 'palaestrai.types.simti... \n", "36 {'denv': {'py/object': 'palaestrai.types.simti... \n", "37 {'denv': {'py/object': 'palaestrai.types.simti... \n", "38 {'denv': {'py/object': 'palaestrai.types.simti... \n", "39 {'denv': {'py/object': 'palaestrai.types.simti... \n", "40 {'denv': {'py/object': 'palaestrai.types.simti... \n", "41 {'denv': {'py/object': 'palaestrai.types.simti... \n", "42 {'denv': {'py/object': 'palaestrai.types.simti... \n", "43 {} \n", "44 {'denv': {'py/object': 'palaestrai.types.simti... \n", "45 {'denv': {'py/object': 'palaestrai.types.simti... \n", "46 {'denv': {'py/object': 'palaestrai.types.simti... \n", "47 {'denv': {'py/object': 'palaestrai.types.simti... \n", "48 {'denv': {'py/object': 'palaestrai.types.simti... \n", "49 {'denv': {'py/object': 'palaestrai.types.simti... \n", "50 {'denv': {'py/object': 'palaestrai.types.simti... \n", "51 {'denv': {'py/object': 'palaestrai.types.simti... \n", "52 {'denv': {'py/object': 'palaestrai.types.simti... \n", "53 {'denv': {'py/object': 'palaestrai.types.simti... \n", "\n", " sensor_readings \\\n", "0 [] \n", "1 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "2 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "3 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "4 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "5 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "6 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "7 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "8 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "9 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "10 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "11 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "12 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "13 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "14 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "15 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "16 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "17 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "18 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "19 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "20 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "21 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "22 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "23 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "24 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "25 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "26 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "27 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "28 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "29 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "30 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "31 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "32 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "33 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "34 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "35 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "36 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "37 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "38 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "39 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "40 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "41 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "42 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "43 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "44 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "45 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "46 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "47 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "48 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "49 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "50 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "51 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "52 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "53 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "\n", " actuator_setpoints \\\n", "0 [] \n", "1 [{'py/object': 'palaestrai.agent.actuator_info... \n", "2 [{'py/object': 'palaestrai.agent.actuator_info... \n", "3 [{'py/object': 'palaestrai.agent.actuator_info... \n", "4 [{'py/object': 'palaestrai.agent.actuator_info... \n", "5 [{'py/object': 'palaestrai.agent.actuator_info... \n", "6 [{'py/object': 'palaestrai.agent.actuator_info... \n", "7 [{'py/object': 'palaestrai.agent.actuator_info... \n", "8 [{'py/object': 'palaestrai.agent.actuator_info... \n", "9 [{'py/object': 'palaestrai.agent.actuator_info... \n", "10 [{'py/object': 'palaestrai.agent.actuator_info... \n", "11 [{'py/object': 'palaestrai.agent.actuator_info... \n", "12 [{'py/object': 'palaestrai.agent.actuator_info... \n", "13 [{'py/object': 'palaestrai.agent.actuator_info... \n", "14 [{'py/object': 'palaestrai.agent.actuator_info... \n", "15 [{'py/object': 'palaestrai.agent.actuator_info... \n", "16 [{'py/object': 'palaestrai.agent.actuator_info... \n", "17 [{'py/object': 'palaestrai.agent.actuator_info... \n", "18 [{'py/object': 'palaestrai.agent.actuator_info... \n", "19 [{'py/object': 'palaestrai.agent.actuator_info... \n", "20 [{'py/object': 'palaestrai.agent.actuator_info... \n", "21 [{'py/object': 'palaestrai.agent.actuator_info... \n", "22 [{'py/object': 'palaestrai.agent.actuator_info... \n", "23 [{'py/object': 'palaestrai.agent.actuator_info... \n", "24 [{'py/object': 'palaestrai.agent.actuator_info... \n", "25 [{'py/object': 'palaestrai.agent.actuator_info... \n", "26 [{'py/object': 'palaestrai.agent.actuator_info... \n", "27 [{'py/object': 'palaestrai.agent.actuator_info... \n", "28 [{'py/object': 'palaestrai.agent.actuator_info... \n", "29 [{'py/object': 'palaestrai.agent.actuator_info... \n", "30 [{'py/object': 'palaestrai.agent.actuator_info... \n", "31 [{'py/object': 'palaestrai.agent.actuator_info... \n", "32 [{'py/object': 'palaestrai.agent.actuator_info... \n", "33 [{'py/object': 'palaestrai.agent.actuator_info... \n", "34 [{'py/object': 'palaestrai.agent.actuator_info... \n", "35 [{'py/object': 'palaestrai.agent.actuator_info... \n", "36 [{'py/object': 'palaestrai.agent.actuator_info... \n", "37 [{'py/object': 'palaestrai.agent.actuator_info... \n", "38 [{'py/object': 'palaestrai.agent.actuator_info... \n", "39 [{'py/object': 'palaestrai.agent.actuator_info... \n", "40 [{'py/object': 'palaestrai.agent.actuator_info... \n", "41 [{'py/object': 'palaestrai.agent.actuator_info... \n", "42 [{'py/object': 'palaestrai.agent.actuator_info... \n", "43 [{'py/object': 'palaestrai.agent.actuator_info... \n", "44 [{'py/object': 'palaestrai.agent.actuator_info... \n", "45 [{'py/object': 'palaestrai.agent.actuator_info... \n", "46 [{'py/object': 'palaestrai.agent.actuator_info... \n", "47 [{'py/object': 'palaestrai.agent.actuator_info... \n", "48 [{'py/object': 'palaestrai.agent.actuator_info... \n", "49 [{'py/object': 'palaestrai.agent.actuator_info... \n", "50 [{'py/object': 'palaestrai.agent.actuator_info... \n", "51 [{'py/object': 'palaestrai.agent.actuator_info... \n", "52 [{'py/object': 'palaestrai.agent.actuator_info... \n", "53 [{'py/object': 'palaestrai.agent.actuator_info... \n", "\n", " rewards objective \n", "0 [{'py/object': 'palaestrai.agent.reward_inform... 0.0 \n", "1 [{'py/object': 'palaestrai.agent.reward_inform... 1.0 \n", "2 [{'py/object': 'palaestrai.agent.reward_inform... 3.0 \n", "3 [{'py/object': 'palaestrai.agent.reward_inform... 6.0 \n", "4 [{'py/object': 'palaestrai.agent.reward_inform... 10.0 \n", "5 [{'py/object': 'palaestrai.agent.reward_inform... 15.0 \n", "6 [{'py/object': 'palaestrai.agent.reward_inform... 21.0 \n", "7 [{'py/object': 'palaestrai.agent.reward_inform... 28.0 \n", "8 [{'py/object': 'palaestrai.agent.reward_inform... 36.0 \n", "9 [{'py/object': 'palaestrai.agent.reward_inform... 45.0 \n", "10 [] 45.0 \n", "11 [{'py/object': 'palaestrai.agent.reward_inform... 45.0 \n", "12 [{'py/object': 'palaestrai.agent.reward_inform... 46.0 \n", "13 [{'py/object': 'palaestrai.agent.reward_inform... 48.0 \n", "14 [{'py/object': 'palaestrai.agent.reward_inform... 51.0 \n", "15 [{'py/object': 'palaestrai.agent.reward_inform... 55.0 \n", "16 [{'py/object': 'palaestrai.agent.reward_inform... 60.0 \n", "17 [{'py/object': 'palaestrai.agent.reward_inform... 66.0 \n", "18 [{'py/object': 'palaestrai.agent.reward_inform... 73.0 \n", "19 [{'py/object': 'palaestrai.agent.reward_inform... 81.0 \n", "20 [{'py/object': 'palaestrai.agent.reward_inform... 90.0 \n", "21 [] 90.0 \n", "22 [{'py/object': 'palaestrai.agent.reward_inform... 90.0 \n", "23 [{'py/object': 'palaestrai.agent.reward_inform... 91.0 \n", "24 [{'py/object': 'palaestrai.agent.reward_inform... 93.0 \n", "25 [{'py/object': 'palaestrai.agent.reward_inform... 96.0 \n", "26 [{'py/object': 'palaestrai.agent.reward_inform... 100.0 \n", "27 [{'py/object': 'palaestrai.agent.reward_inform... 105.0 \n", "28 [{'py/object': 'palaestrai.agent.reward_inform... 111.0 \n", "29 [{'py/object': 'palaestrai.agent.reward_inform... 118.0 \n", "30 [{'py/object': 'palaestrai.agent.reward_inform... 126.0 \n", "31 [{'py/object': 'palaestrai.agent.reward_inform... 135.0 \n", "32 [] 135.0 \n", "33 [{'py/object': 'palaestrai.agent.reward_inform... 135.0 \n", "34 [{'py/object': 'palaestrai.agent.reward_inform... 136.0 \n", "35 [{'py/object': 'palaestrai.agent.reward_inform... 138.0 \n", "36 [{'py/object': 'palaestrai.agent.reward_inform... 141.0 \n", "37 [{'py/object': 'palaestrai.agent.reward_inform... 145.0 \n", "38 [{'py/object': 'palaestrai.agent.reward_inform... 150.0 \n", "39 [{'py/object': 'palaestrai.agent.reward_inform... 156.0 \n", "40 [{'py/object': 'palaestrai.agent.reward_inform... 163.0 \n", "41 [{'py/object': 'palaestrai.agent.reward_inform... 171.0 \n", "42 [{'py/object': 'palaestrai.agent.reward_inform... 180.0 \n", "43 [] 180.0 \n", "44 [{'py/object': 'palaestrai.agent.reward_inform... 180.0 \n", "45 [{'py/object': 'palaestrai.agent.reward_inform... 181.0 \n", "46 [{'py/object': 'palaestrai.agent.reward_inform... 183.0 \n", "47 [{'py/object': 'palaestrai.agent.reward_inform... 186.0 \n", "48 [{'py/object': 'palaestrai.agent.reward_inform... 190.0 \n", "49 [{'py/object': 'palaestrai.agent.reward_inform... 195.0 \n", "50 [{'py/object': 'palaestrai.agent.reward_inform... 201.0 \n", "51 [{'py/object': 'palaestrai.agent.reward_inform... 208.0 \n", "52 [{'py/object': 'palaestrai.agent.reward_inform... 216.0 \n", "53 [{'py/object': 'palaestrai.agent.reward_inform... 225.0 " ] }, "execution_count": 70, "metadata": {}, "output_type": "execute_result" } ], "source": [ "actions = pd.read_sql(\n", " sa.select(paldb.MuscleAction).where(\n", " paldb.MuscleAction.agent_id == agent_record.id\n", " ),\n", " dbh.bind,\n", ")\n", "actions" ] }, { "cell_type": "markdown", "id": "55f697e0", "metadata": {}, "source": [ "Okay, but how do we get rewards out of this? The `rewards` column contains a list of `RewardInformation` objects. In our case, we know that there will ever be only one (more than one is a special case). We also know that there will always be a `float`. The knowledge about this comes from our knowledge of the reward, i.e., it is really domain knowledge that an experimenter will have.\n", "\n", "At this point, we need to modify the dataframe a bit. We have to call `jsonpickle.loads()` to get the object, and then extract the reward out of it. `DataFrame.apply()` solves us well here. In order to make it more readable, we provide a function for this." ] }, { "cell_type": "code", "execution_count": 76, "id": "321c68bd", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
idwalltimeagent_idsimtimessensor_readingsactuator_setpointsrewardsobjective
012023-12-13 14:04:42.2382461{'denv': {'py/object': 'palaestrai.types.simti...[][]0.00.0
122023-12-13 14:04:42.2697781{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...1.01.0
232023-12-13 14:04:42.2983541{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...2.03.0
342023-12-13 14:04:42.3248101{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...3.06.0
452023-12-13 14:04:42.3540931{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...4.010.0
562023-12-13 14:04:42.3827571{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...5.015.0
672023-12-13 14:04:42.4107071{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...6.021.0
782023-12-13 14:04:42.4396301{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...7.028.0
892023-12-13 14:04:42.4695561{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...8.036.0
9102023-12-13 14:04:42.4977251{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...9.045.0
10112023-12-13 14:04:42.5310331{}[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...0.045.0
11122023-12-13 14:04:42.5596941{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...0.045.0
12132023-12-13 14:04:42.5890401{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...1.046.0
13142023-12-13 14:04:42.6182501{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...2.048.0
14152023-12-13 14:04:42.6477491{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...3.051.0
15162023-12-13 14:04:42.6752421{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...4.055.0
16172023-12-13 14:04:42.7066401{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...5.060.0
17182023-12-13 14:04:42.7348831{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...6.066.0
18192023-12-13 14:04:42.7633091{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...7.073.0
19202023-12-13 14:04:42.7915861{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...8.081.0
20212023-12-13 14:04:42.8203771{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...9.090.0
21222023-12-13 14:04:42.8528971{}[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...0.090.0
22232023-12-13 14:04:42.8821831{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...0.090.0
23242023-12-13 14:04:42.9149381{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...1.091.0
24252023-12-13 14:04:42.9496411{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...2.093.0
25262023-12-13 14:04:42.9898571{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...3.096.0
26272023-12-13 14:04:43.0233441{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...4.0100.0
27282023-12-13 14:04:43.0559701{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...5.0105.0
28292023-12-13 14:04:43.0865481{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...6.0111.0
29302023-12-13 14:04:43.1246221{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...7.0118.0
30312023-12-13 14:04:43.1562421{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...8.0126.0
31322023-12-13 14:04:43.1875641{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...9.0135.0
32332023-12-13 14:04:43.2246151{}[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...0.0135.0
33342023-12-13 14:04:43.2555821{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...0.0135.0
34352023-12-13 14:04:43.2870021{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...1.0136.0
35362023-12-13 14:04:43.3216051{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...2.0138.0
36372023-12-13 14:04:43.3532631{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...3.0141.0
37382023-12-13 14:04:43.3836041{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...4.0145.0
38392023-12-13 14:04:43.4139911{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...5.0150.0
39402023-12-13 14:04:43.4465561{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...6.0156.0
40412023-12-13 14:04:43.4761321{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...7.0163.0
41422023-12-13 14:04:43.5057111{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...8.0171.0
42432023-12-13 14:04:43.5367841{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...9.0180.0
43442023-12-13 14:04:43.5765471{}[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...0.0180.0
44452023-12-13 14:04:43.6076401{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...0.0180.0
45462023-12-13 14:04:43.6387261{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...1.0181.0
46472023-12-13 14:04:43.6717911{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...2.0183.0
47482023-12-13 14:04:43.7046901{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...3.0186.0
48492023-12-13 14:04:43.7397401{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...4.0190.0
49502023-12-13 14:04:43.7746561{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...5.0195.0
50512023-12-13 14:04:43.8215131{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...6.0201.0
51522023-12-13 14:04:43.8570551{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...7.0208.0
52532023-12-13 14:04:43.8938551{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...8.0216.0
53542023-12-13 14:04:43.9303491{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...9.0225.0
\n", "
" ], "text/plain": [ " id walltime agent_id \\\n", "0 1 2023-12-13 14:04:42.238246 1 \n", "1 2 2023-12-13 14:04:42.269778 1 \n", "2 3 2023-12-13 14:04:42.298354 1 \n", "3 4 2023-12-13 14:04:42.324810 1 \n", "4 5 2023-12-13 14:04:42.354093 1 \n", "5 6 2023-12-13 14:04:42.382757 1 \n", "6 7 2023-12-13 14:04:42.410707 1 \n", "7 8 2023-12-13 14:04:42.439630 1 \n", "8 9 2023-12-13 14:04:42.469556 1 \n", "9 10 2023-12-13 14:04:42.497725 1 \n", "10 11 2023-12-13 14:04:42.531033 1 \n", "11 12 2023-12-13 14:04:42.559694 1 \n", "12 13 2023-12-13 14:04:42.589040 1 \n", "13 14 2023-12-13 14:04:42.618250 1 \n", "14 15 2023-12-13 14:04:42.647749 1 \n", "15 16 2023-12-13 14:04:42.675242 1 \n", "16 17 2023-12-13 14:04:42.706640 1 \n", "17 18 2023-12-13 14:04:42.734883 1 \n", "18 19 2023-12-13 14:04:42.763309 1 \n", "19 20 2023-12-13 14:04:42.791586 1 \n", "20 21 2023-12-13 14:04:42.820377 1 \n", "21 22 2023-12-13 14:04:42.852897 1 \n", "22 23 2023-12-13 14:04:42.882183 1 \n", "23 24 2023-12-13 14:04:42.914938 1 \n", "24 25 2023-12-13 14:04:42.949641 1 \n", "25 26 2023-12-13 14:04:42.989857 1 \n", "26 27 2023-12-13 14:04:43.023344 1 \n", "27 28 2023-12-13 14:04:43.055970 1 \n", "28 29 2023-12-13 14:04:43.086548 1 \n", "29 30 2023-12-13 14:04:43.124622 1 \n", "30 31 2023-12-13 14:04:43.156242 1 \n", "31 32 2023-12-13 14:04:43.187564 1 \n", "32 33 2023-12-13 14:04:43.224615 1 \n", "33 34 2023-12-13 14:04:43.255582 1 \n", "34 35 2023-12-13 14:04:43.287002 1 \n", "35 36 2023-12-13 14:04:43.321605 1 \n", "36 37 2023-12-13 14:04:43.353263 1 \n", "37 38 2023-12-13 14:04:43.383604 1 \n", "38 39 2023-12-13 14:04:43.413991 1 \n", "39 40 2023-12-13 14:04:43.446556 1 \n", "40 41 2023-12-13 14:04:43.476132 1 \n", "41 42 2023-12-13 14:04:43.505711 1 \n", "42 43 2023-12-13 14:04:43.536784 1 \n", "43 44 2023-12-13 14:04:43.576547 1 \n", "44 45 2023-12-13 14:04:43.607640 1 \n", "45 46 2023-12-13 14:04:43.638726 1 \n", "46 47 2023-12-13 14:04:43.671791 1 \n", "47 48 2023-12-13 14:04:43.704690 1 \n", "48 49 2023-12-13 14:04:43.739740 1 \n", "49 50 2023-12-13 14:04:43.774656 1 \n", "50 51 2023-12-13 14:04:43.821513 1 \n", "51 52 2023-12-13 14:04:43.857055 1 \n", "52 53 2023-12-13 14:04:43.893855 1 \n", "53 54 2023-12-13 14:04:43.930349 1 \n", "\n", " simtimes \\\n", "0 {'denv': {'py/object': 'palaestrai.types.simti... \n", "1 {'denv': {'py/object': 'palaestrai.types.simti... \n", "2 {'denv': {'py/object': 'palaestrai.types.simti... \n", "3 {'denv': {'py/object': 'palaestrai.types.simti... \n", "4 {'denv': {'py/object': 'palaestrai.types.simti... \n", "5 {'denv': {'py/object': 'palaestrai.types.simti... \n", "6 {'denv': {'py/object': 'palaestrai.types.simti... \n", "7 {'denv': {'py/object': 'palaestrai.types.simti... \n", "8 {'denv': {'py/object': 'palaestrai.types.simti... \n", "9 {'denv': {'py/object': 'palaestrai.types.simti... \n", "10 {} \n", "11 {'denv': {'py/object': 'palaestrai.types.simti... \n", "12 {'denv': {'py/object': 'palaestrai.types.simti... \n", "13 {'denv': {'py/object': 'palaestrai.types.simti... \n", "14 {'denv': {'py/object': 'palaestrai.types.simti... \n", "15 {'denv': {'py/object': 'palaestrai.types.simti... \n", "16 {'denv': {'py/object': 'palaestrai.types.simti... \n", "17 {'denv': {'py/object': 'palaestrai.types.simti... \n", "18 {'denv': {'py/object': 'palaestrai.types.simti... \n", "19 {'denv': {'py/object': 'palaestrai.types.simti... \n", "20 {'denv': {'py/object': 'palaestrai.types.simti... \n", "21 {} \n", "22 {'denv': {'py/object': 'palaestrai.types.simti... \n", "23 {'denv': {'py/object': 'palaestrai.types.simti... \n", "24 {'denv': {'py/object': 'palaestrai.types.simti... \n", "25 {'denv': {'py/object': 'palaestrai.types.simti... \n", "26 {'denv': {'py/object': 'palaestrai.types.simti... \n", "27 {'denv': {'py/object': 'palaestrai.types.simti... \n", "28 {'denv': {'py/object': 'palaestrai.types.simti... \n", "29 {'denv': {'py/object': 'palaestrai.types.simti... \n", "30 {'denv': {'py/object': 'palaestrai.types.simti... \n", "31 {'denv': {'py/object': 'palaestrai.types.simti... \n", "32 {} \n", "33 {'denv': {'py/object': 'palaestrai.types.simti... \n", "34 {'denv': {'py/object': 'palaestrai.types.simti... \n", "35 {'denv': {'py/object': 'palaestrai.types.simti... \n", "36 {'denv': {'py/object': 'palaestrai.types.simti... \n", "37 {'denv': {'py/object': 'palaestrai.types.simti... \n", "38 {'denv': {'py/object': 'palaestrai.types.simti... \n", "39 {'denv': {'py/object': 'palaestrai.types.simti... \n", "40 {'denv': {'py/object': 'palaestrai.types.simti... \n", "41 {'denv': {'py/object': 'palaestrai.types.simti... \n", "42 {'denv': {'py/object': 'palaestrai.types.simti... \n", "43 {} \n", "44 {'denv': {'py/object': 'palaestrai.types.simti... \n", "45 {'denv': {'py/object': 'palaestrai.types.simti... \n", "46 {'denv': {'py/object': 'palaestrai.types.simti... \n", "47 {'denv': {'py/object': 'palaestrai.types.simti... \n", "48 {'denv': {'py/object': 'palaestrai.types.simti... \n", "49 {'denv': {'py/object': 'palaestrai.types.simti... \n", "50 {'denv': {'py/object': 'palaestrai.types.simti... \n", "51 {'denv': {'py/object': 'palaestrai.types.simti... \n", "52 {'denv': {'py/object': 'palaestrai.types.simti... \n", "53 {'denv': {'py/object': 'palaestrai.types.simti... \n", "\n", " sensor_readings \\\n", "0 [] \n", "1 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "2 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "3 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "4 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "5 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "6 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "7 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "8 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "9 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "10 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "11 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "12 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "13 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "14 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "15 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "16 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "17 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "18 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "19 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "20 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "21 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "22 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "23 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "24 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "25 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "26 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "27 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "28 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "29 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "30 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "31 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "32 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "33 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "34 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "35 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "36 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "37 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "38 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "39 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "40 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "41 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "42 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "43 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "44 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "45 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "46 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "47 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "48 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "49 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "50 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "51 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "52 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "53 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "\n", " actuator_setpoints rewards objective \n", "0 [] 0.0 0.0 \n", "1 [{'py/object': 'palaestrai.agent.actuator_info... 1.0 1.0 \n", "2 [{'py/object': 'palaestrai.agent.actuator_info... 2.0 3.0 \n", "3 [{'py/object': 'palaestrai.agent.actuator_info... 3.0 6.0 \n", "4 [{'py/object': 'palaestrai.agent.actuator_info... 4.0 10.0 \n", "5 [{'py/object': 'palaestrai.agent.actuator_info... 5.0 15.0 \n", "6 [{'py/object': 'palaestrai.agent.actuator_info... 6.0 21.0 \n", "7 [{'py/object': 'palaestrai.agent.actuator_info... 7.0 28.0 \n", "8 [{'py/object': 'palaestrai.agent.actuator_info... 8.0 36.0 \n", "9 [{'py/object': 'palaestrai.agent.actuator_info... 9.0 45.0 \n", "10 [{'py/object': 'palaestrai.agent.actuator_info... 0.0 45.0 \n", "11 [{'py/object': 'palaestrai.agent.actuator_info... 0.0 45.0 \n", "12 [{'py/object': 'palaestrai.agent.actuator_info... 1.0 46.0 \n", "13 [{'py/object': 'palaestrai.agent.actuator_info... 2.0 48.0 \n", "14 [{'py/object': 'palaestrai.agent.actuator_info... 3.0 51.0 \n", "15 [{'py/object': 'palaestrai.agent.actuator_info... 4.0 55.0 \n", "16 [{'py/object': 'palaestrai.agent.actuator_info... 5.0 60.0 \n", "17 [{'py/object': 'palaestrai.agent.actuator_info... 6.0 66.0 \n", "18 [{'py/object': 'palaestrai.agent.actuator_info... 7.0 73.0 \n", "19 [{'py/object': 'palaestrai.agent.actuator_info... 8.0 81.0 \n", "20 [{'py/object': 'palaestrai.agent.actuator_info... 9.0 90.0 \n", "21 [{'py/object': 'palaestrai.agent.actuator_info... 0.0 90.0 \n", "22 [{'py/object': 'palaestrai.agent.actuator_info... 0.0 90.0 \n", "23 [{'py/object': 'palaestrai.agent.actuator_info... 1.0 91.0 \n", "24 [{'py/object': 'palaestrai.agent.actuator_info... 2.0 93.0 \n", "25 [{'py/object': 'palaestrai.agent.actuator_info... 3.0 96.0 \n", "26 [{'py/object': 'palaestrai.agent.actuator_info... 4.0 100.0 \n", "27 [{'py/object': 'palaestrai.agent.actuator_info... 5.0 105.0 \n", "28 [{'py/object': 'palaestrai.agent.actuator_info... 6.0 111.0 \n", "29 [{'py/object': 'palaestrai.agent.actuator_info... 7.0 118.0 \n", "30 [{'py/object': 'palaestrai.agent.actuator_info... 8.0 126.0 \n", "31 [{'py/object': 'palaestrai.agent.actuator_info... 9.0 135.0 \n", "32 [{'py/object': 'palaestrai.agent.actuator_info... 0.0 135.0 \n", "33 [{'py/object': 'palaestrai.agent.actuator_info... 0.0 135.0 \n", "34 [{'py/object': 'palaestrai.agent.actuator_info... 1.0 136.0 \n", "35 [{'py/object': 'palaestrai.agent.actuator_info... 2.0 138.0 \n", "36 [{'py/object': 'palaestrai.agent.actuator_info... 3.0 141.0 \n", "37 [{'py/object': 'palaestrai.agent.actuator_info... 4.0 145.0 \n", "38 [{'py/object': 'palaestrai.agent.actuator_info... 5.0 150.0 \n", "39 [{'py/object': 'palaestrai.agent.actuator_info... 6.0 156.0 \n", "40 [{'py/object': 'palaestrai.agent.actuator_info... 7.0 163.0 \n", "41 [{'py/object': 'palaestrai.agent.actuator_info... 8.0 171.0 \n", "42 [{'py/object': 'palaestrai.agent.actuator_info... 9.0 180.0 \n", "43 [{'py/object': 'palaestrai.agent.actuator_info... 0.0 180.0 \n", "44 [{'py/object': 'palaestrai.agent.actuator_info... 0.0 180.0 \n", "45 [{'py/object': 'palaestrai.agent.actuator_info... 1.0 181.0 \n", "46 [{'py/object': 'palaestrai.agent.actuator_info... 2.0 183.0 \n", "47 [{'py/object': 'palaestrai.agent.actuator_info... 3.0 186.0 \n", "48 [{'py/object': 'palaestrai.agent.actuator_info... 4.0 190.0 \n", "49 [{'py/object': 'palaestrai.agent.actuator_info... 5.0 195.0 \n", "50 [{'py/object': 'palaestrai.agent.actuator_info... 6.0 201.0 \n", "51 [{'py/object': 'palaestrai.agent.actuator_info... 7.0 208.0 \n", "52 [{'py/object': 'palaestrai.agent.actuator_info... 8.0 216.0 \n", "53 [{'py/object': 'palaestrai.agent.actuator_info... 9.0 225.0 " ] }, "execution_count": 76, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def unpack_reward(x):\n", " return float(x[0][\"py/state\"][\"value\"]) if x else 0.0\n", "\n", "\n", "actions.rewards = actions.rewards.apply(lambda x: unpack_reward(x))\n", "actions" ] }, { "cell_type": "markdown", "id": "1938151e", "metadata": {}, "source": [ "Plotting is relatively easy now, as pandas already provides us with everything we need." ] }, { "cell_type": "code", "execution_count": 77, "id": "9df35acd", "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 77, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "actions.plot(x=\"id\", y=\"rewards\", kind=\"scatter\")" ] }, { "cell_type": "markdown", "id": "849a5726", "metadata": {}, "source": [ "Okay, but if we want to compare the agents' performance during the testing phase? First we need to find out what agents participated in the last experiment run phase. So let's return to the experiment run phases table:" ] }, { "cell_type": "code", "execution_count": 78, "id": "d10eb910", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
iduidnamemusclesconfigurationexperiment_run_phase_id
04mighty_defendermighty_defender[Tutorial Experiment Run_A:4bb49b68-0870-474b-...{'name': 'mighty_defender', 'brain': {'name': ...3
15evil_attackerevil_attacker[Tutorial Experiment Run_A:89555042-cabb-4077-...{'name': 'evil_attacker', 'brain': {'name': 'p...3
22mighty_defendermighty_defender[Tutorial Experiment Run_A:814e074f-1182-41c1-...{'name': 'mighty_defender', 'brain': {'name': ...2
33evil_attackerevil_attacker[Tutorial Experiment Run_A:914d21dd-fd8b-43cf-...{'name': 'evil_attacker', 'brain': {'name': 'p...2
41mighty_defendermighty_defender[Tutorial Experiment Run_A:0fde7238-1e1b-4c2e-...{'name': 'mighty_defender', 'brain': {'name': ...1
\n", "
" ], "text/plain": [ " id uid name \\\n", "0 4 mighty_defender mighty_defender \n", "1 5 evil_attacker evil_attacker \n", "2 2 mighty_defender mighty_defender \n", "3 3 evil_attacker evil_attacker \n", "4 1 mighty_defender mighty_defender \n", "\n", " muscles \\\n", "0 [Tutorial Experiment Run_A:4bb49b68-0870-474b-... \n", "1 [Tutorial Experiment Run_A:89555042-cabb-4077-... \n", "2 [Tutorial Experiment Run_A:814e074f-1182-41c1-... \n", "3 [Tutorial Experiment Run_A:914d21dd-fd8b-43cf-... \n", "4 [Tutorial Experiment Run_A:0fde7238-1e1b-4c2e-... \n", "\n", " configuration experiment_run_phase_id \n", "0 {'name': 'mighty_defender', 'brain': {'name': ... 3 \n", "1 {'name': 'evil_attacker', 'brain': {'name': 'p... 3 \n", "2 {'name': 'mighty_defender', 'brain': {'name': ... 2 \n", "3 {'name': 'evil_attacker', 'brain': {'name': 'p... 2 \n", "4 {'name': 'mighty_defender', 'brain': {'name': ... 1 " ] }, "execution_count": 78, "metadata": {}, "output_type": "execute_result" } ], "source": [ "experiment_run_phases = pd.read_sql(\n", " sa.select(paldb.Agent)\n", " .where(\n", " paldb.Agent.experiment_run_phase_id.in_(\n", " phase.id\n", " for phase in experiment_run_record.experiment_run_instances[\n", " 0\n", " ].experiment_run_phases\n", " )\n", " )\n", " .order_by(paldb.Agent.experiment_run_phase_id.desc()),\n", " dbh.bind,\n", ")\n", "experiment_run_phases" ] }, { "cell_type": "markdown", "id": "642b18b5", "metadata": {}, "source": [ "Okay, the top two rows are the ones we want to look at." ] }, { "cell_type": "code", "execution_count": 79, "id": "c3786fba", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
iduidnamemusclesconfigurationexperiment_run_phase_idid_1walltimeagent_idsimtimessensor_readingsactuator_setpointsrewardsobjective
04mighty_defendermighty_defender[Tutorial Experiment Run_A:4bb49b68-0870-474b-...{'name': 'mighty_defender', 'brain': {'name': ...3972023-12-13 14:05:15.9920594{'denv': {'py/object': 'palaestrai.types.simti...[][][{'py/object': 'palaestrai.agent.reward_inform...0.0
15evil_attackerevil_attacker[Tutorial Experiment Run_A:89555042-cabb-4077-...{'name': 'evil_attacker', 'brain': {'name': 'p...3982023-12-13 14:05:16.0495755{'denv': {'py/object': 'palaestrai.types.simti...[][][{'py/object': 'palaestrai.agent.reward_inform...0.0
24mighty_defendermighty_defender[Tutorial Experiment Run_A:4bb49b68-0870-474b-...{'name': 'mighty_defender', 'brain': {'name': ...3992023-12-13 14:05:16.0790004{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...1.0
35evil_attackerevil_attacker[Tutorial Experiment Run_A:89555042-cabb-4077-...{'name': 'evil_attacker', 'brain': {'name': 'p...31002023-12-13 14:05:16.0794625{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...1.0
45evil_attackerevil_attacker[Tutorial Experiment Run_A:89555042-cabb-4077-...{'name': 'evil_attacker', 'brain': {'name': 'p...31012023-12-13 14:05:16.1102105{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...3.0
.............................................
594mighty_defendermighty_defender[Tutorial Experiment Run_A:4bb49b68-0870-474b-...{'name': 'mighty_defender', 'brain': {'name': ...31562023-12-13 14:05:17.0083384{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...118.0
604mighty_defendermighty_defender[Tutorial Experiment Run_A:4bb49b68-0870-474b-...{'name': 'mighty_defender', 'brain': {'name': ...31572023-12-13 14:05:17.0414154{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...126.0
615evil_attackerevil_attacker[Tutorial Experiment Run_A:89555042-cabb-4077-...{'name': 'evil_attacker', 'brain': {'name': 'p...31582023-12-13 14:05:17.0446705{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...126.0
624mighty_defendermighty_defender[Tutorial Experiment Run_A:4bb49b68-0870-474b-...{'name': 'mighty_defender', 'brain': {'name': ...31592023-12-13 14:05:17.0766804{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...135.0
635evil_attackerevil_attacker[Tutorial Experiment Run_A:89555042-cabb-4077-...{'name': 'evil_attacker', 'brain': {'name': 'p...31602023-12-13 14:05:17.0770745{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...[{'py/object': 'palaestrai.agent.reward_inform...135.0
\n", "

64 rows × 14 columns

\n", "
" ], "text/plain": [ " id uid name \\\n", "0 4 mighty_defender mighty_defender \n", "1 5 evil_attacker evil_attacker \n", "2 4 mighty_defender mighty_defender \n", "3 5 evil_attacker evil_attacker \n", "4 5 evil_attacker evil_attacker \n", ".. .. ... ... \n", "59 4 mighty_defender mighty_defender \n", "60 4 mighty_defender mighty_defender \n", "61 5 evil_attacker evil_attacker \n", "62 4 mighty_defender mighty_defender \n", "63 5 evil_attacker evil_attacker \n", "\n", " muscles \\\n", "0 [Tutorial Experiment Run_A:4bb49b68-0870-474b-... \n", "1 [Tutorial Experiment Run_A:89555042-cabb-4077-... \n", "2 [Tutorial Experiment Run_A:4bb49b68-0870-474b-... \n", "3 [Tutorial Experiment Run_A:89555042-cabb-4077-... \n", "4 [Tutorial Experiment Run_A:89555042-cabb-4077-... \n", ".. ... \n", "59 [Tutorial Experiment Run_A:4bb49b68-0870-474b-... \n", "60 [Tutorial Experiment Run_A:4bb49b68-0870-474b-... \n", "61 [Tutorial Experiment Run_A:89555042-cabb-4077-... \n", "62 [Tutorial Experiment Run_A:4bb49b68-0870-474b-... \n", "63 [Tutorial Experiment Run_A:89555042-cabb-4077-... \n", "\n", " configuration \\\n", "0 {'name': 'mighty_defender', 'brain': {'name': ... \n", "1 {'name': 'evil_attacker', 'brain': {'name': 'p... \n", "2 {'name': 'mighty_defender', 'brain': {'name': ... \n", "3 {'name': 'evil_attacker', 'brain': {'name': 'p... \n", "4 {'name': 'evil_attacker', 'brain': {'name': 'p... \n", ".. ... \n", "59 {'name': 'mighty_defender', 'brain': {'name': ... \n", "60 {'name': 'mighty_defender', 'brain': {'name': ... \n", "61 {'name': 'evil_attacker', 'brain': {'name': 'p... \n", "62 {'name': 'mighty_defender', 'brain': {'name': ... \n", "63 {'name': 'evil_attacker', 'brain': {'name': 'p... \n", "\n", " experiment_run_phase_id id_1 walltime agent_id \\\n", "0 3 97 2023-12-13 14:05:15.992059 4 \n", "1 3 98 2023-12-13 14:05:16.049575 5 \n", "2 3 99 2023-12-13 14:05:16.079000 4 \n", "3 3 100 2023-12-13 14:05:16.079462 5 \n", "4 3 101 2023-12-13 14:05:16.110210 5 \n", ".. ... ... ... ... \n", "59 3 156 2023-12-13 14:05:17.008338 4 \n", "60 3 157 2023-12-13 14:05:17.041415 4 \n", "61 3 158 2023-12-13 14:05:17.044670 5 \n", "62 3 159 2023-12-13 14:05:17.076680 4 \n", "63 3 160 2023-12-13 14:05:17.077074 5 \n", "\n", " simtimes \\\n", "0 {'denv': {'py/object': 'palaestrai.types.simti... \n", "1 {'denv': {'py/object': 'palaestrai.types.simti... \n", "2 {'denv': {'py/object': 'palaestrai.types.simti... \n", "3 {'denv': {'py/object': 'palaestrai.types.simti... \n", "4 {'denv': {'py/object': 'palaestrai.types.simti... \n", ".. ... \n", "59 {'denv': {'py/object': 'palaestrai.types.simti... \n", "60 {'denv': {'py/object': 'palaestrai.types.simti... \n", "61 {'denv': {'py/object': 'palaestrai.types.simti... \n", "62 {'denv': {'py/object': 'palaestrai.types.simti... \n", "63 {'denv': {'py/object': 'palaestrai.types.simti... \n", "\n", " sensor_readings \\\n", "0 [] \n", "1 [] \n", "2 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "3 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "4 [{'py/object': 'palaestrai.agent.sensor_inform... \n", ".. ... \n", "59 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "60 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "61 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "62 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "63 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "\n", " actuator_setpoints \\\n", "0 [] \n", "1 [] \n", "2 [{'py/object': 'palaestrai.agent.actuator_info... \n", "3 [{'py/object': 'palaestrai.agent.actuator_info... \n", "4 [{'py/object': 'palaestrai.agent.actuator_info... \n", ".. ... \n", "59 [{'py/object': 'palaestrai.agent.actuator_info... \n", "60 [{'py/object': 'palaestrai.agent.actuator_info... \n", "61 [{'py/object': 'palaestrai.agent.actuator_info... \n", "62 [{'py/object': 'palaestrai.agent.actuator_info... \n", "63 [{'py/object': 'palaestrai.agent.actuator_info... \n", "\n", " rewards objective \n", "0 [{'py/object': 'palaestrai.agent.reward_inform... 0.0 \n", "1 [{'py/object': 'palaestrai.agent.reward_inform... 0.0 \n", "2 [{'py/object': 'palaestrai.agent.reward_inform... 1.0 \n", "3 [{'py/object': 'palaestrai.agent.reward_inform... 1.0 \n", "4 [{'py/object': 'palaestrai.agent.reward_inform... 3.0 \n", ".. ... ... \n", "59 [{'py/object': 'palaestrai.agent.reward_inform... 118.0 \n", "60 [{'py/object': 'palaestrai.agent.reward_inform... 126.0 \n", "61 [{'py/object': 'palaestrai.agent.reward_inform... 126.0 \n", "62 [{'py/object': 'palaestrai.agent.reward_inform... 135.0 \n", "63 [{'py/object': 'palaestrai.agent.reward_inform... 135.0 \n", "\n", "[64 rows x 14 columns]" ] }, "execution_count": 79, "metadata": {}, "output_type": "execute_result" } ], "source": [ "muscle_actions = pd.read_sql(\n", " sa.select(paldb.Agent, paldb.MuscleAction)\n", " .join(paldb.Agent.muscle_actions)\n", " .where(\n", " paldb.Agent.experiment_run_phase_id.in_(\n", " experiment_run_phases.experiment_run_phase_id[0:2]\n", " )\n", " ),\n", " dbh.bind,\n", ")\n", "assert len(muscle_actions) > 2\n", "muscle_actions" ] }, { "cell_type": "markdown", "id": "56316683", "metadata": {}, "source": [ "Let's do the reward conversion dance:" ] }, { "cell_type": "code", "execution_count": 80, "id": "3b4947c8", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
iduidnamemusclesconfigurationexperiment_run_phase_idid_1walltimeagent_idsimtimessensor_readingsactuator_setpointsrewardsobjective
04mighty_defendermighty_defender[Tutorial Experiment Run_A:4bb49b68-0870-474b-...{'name': 'mighty_defender', 'brain': {'name': ...3972023-12-13 14:05:15.9920594{'denv': {'py/object': 'palaestrai.types.simti...[][]0.00.0
15evil_attackerevil_attacker[Tutorial Experiment Run_A:89555042-cabb-4077-...{'name': 'evil_attacker', 'brain': {'name': 'p...3982023-12-13 14:05:16.0495755{'denv': {'py/object': 'palaestrai.types.simti...[][]0.00.0
24mighty_defendermighty_defender[Tutorial Experiment Run_A:4bb49b68-0870-474b-...{'name': 'mighty_defender', 'brain': {'name': ...3992023-12-13 14:05:16.0790004{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...1.01.0
35evil_attackerevil_attacker[Tutorial Experiment Run_A:89555042-cabb-4077-...{'name': 'evil_attacker', 'brain': {'name': 'p...31002023-12-13 14:05:16.0794625{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...1.01.0
45evil_attackerevil_attacker[Tutorial Experiment Run_A:89555042-cabb-4077-...{'name': 'evil_attacker', 'brain': {'name': 'p...31012023-12-13 14:05:16.1102105{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...2.03.0
.............................................
594mighty_defendermighty_defender[Tutorial Experiment Run_A:4bb49b68-0870-474b-...{'name': 'mighty_defender', 'brain': {'name': ...31562023-12-13 14:05:17.0083384{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...7.0118.0
604mighty_defendermighty_defender[Tutorial Experiment Run_A:4bb49b68-0870-474b-...{'name': 'mighty_defender', 'brain': {'name': ...31572023-12-13 14:05:17.0414154{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...8.0126.0
615evil_attackerevil_attacker[Tutorial Experiment Run_A:89555042-cabb-4077-...{'name': 'evil_attacker', 'brain': {'name': 'p...31582023-12-13 14:05:17.0446705{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...8.0126.0
624mighty_defendermighty_defender[Tutorial Experiment Run_A:4bb49b68-0870-474b-...{'name': 'mighty_defender', 'brain': {'name': ...31592023-12-13 14:05:17.0766804{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...9.0135.0
635evil_attackerevil_attacker[Tutorial Experiment Run_A:89555042-cabb-4077-...{'name': 'evil_attacker', 'brain': {'name': 'p...31602023-12-13 14:05:17.0770745{'denv': {'py/object': 'palaestrai.types.simti...[{'py/object': 'palaestrai.agent.sensor_inform...[{'py/object': 'palaestrai.agent.actuator_info...9.0135.0
\n", "

64 rows × 14 columns

\n", "
" ], "text/plain": [ " id uid name \\\n", "0 4 mighty_defender mighty_defender \n", "1 5 evil_attacker evil_attacker \n", "2 4 mighty_defender mighty_defender \n", "3 5 evil_attacker evil_attacker \n", "4 5 evil_attacker evil_attacker \n", ".. .. ... ... \n", "59 4 mighty_defender mighty_defender \n", "60 4 mighty_defender mighty_defender \n", "61 5 evil_attacker evil_attacker \n", "62 4 mighty_defender mighty_defender \n", "63 5 evil_attacker evil_attacker \n", "\n", " muscles \\\n", "0 [Tutorial Experiment Run_A:4bb49b68-0870-474b-... \n", "1 [Tutorial Experiment Run_A:89555042-cabb-4077-... \n", "2 [Tutorial Experiment Run_A:4bb49b68-0870-474b-... \n", "3 [Tutorial Experiment Run_A:89555042-cabb-4077-... \n", "4 [Tutorial Experiment Run_A:89555042-cabb-4077-... \n", ".. ... \n", "59 [Tutorial Experiment Run_A:4bb49b68-0870-474b-... \n", "60 [Tutorial Experiment Run_A:4bb49b68-0870-474b-... \n", "61 [Tutorial Experiment Run_A:89555042-cabb-4077-... \n", "62 [Tutorial Experiment Run_A:4bb49b68-0870-474b-... \n", "63 [Tutorial Experiment Run_A:89555042-cabb-4077-... \n", "\n", " configuration \\\n", "0 {'name': 'mighty_defender', 'brain': {'name': ... \n", "1 {'name': 'evil_attacker', 'brain': {'name': 'p... \n", "2 {'name': 'mighty_defender', 'brain': {'name': ... \n", "3 {'name': 'evil_attacker', 'brain': {'name': 'p... \n", "4 {'name': 'evil_attacker', 'brain': {'name': 'p... \n", ".. ... \n", "59 {'name': 'mighty_defender', 'brain': {'name': ... \n", "60 {'name': 'mighty_defender', 'brain': {'name': ... \n", "61 {'name': 'evil_attacker', 'brain': {'name': 'p... \n", "62 {'name': 'mighty_defender', 'brain': {'name': ... \n", "63 {'name': 'evil_attacker', 'brain': {'name': 'p... \n", "\n", " experiment_run_phase_id id_1 walltime agent_id \\\n", "0 3 97 2023-12-13 14:05:15.992059 4 \n", "1 3 98 2023-12-13 14:05:16.049575 5 \n", "2 3 99 2023-12-13 14:05:16.079000 4 \n", "3 3 100 2023-12-13 14:05:16.079462 5 \n", "4 3 101 2023-12-13 14:05:16.110210 5 \n", ".. ... ... ... ... \n", "59 3 156 2023-12-13 14:05:17.008338 4 \n", "60 3 157 2023-12-13 14:05:17.041415 4 \n", "61 3 158 2023-12-13 14:05:17.044670 5 \n", "62 3 159 2023-12-13 14:05:17.076680 4 \n", "63 3 160 2023-12-13 14:05:17.077074 5 \n", "\n", " simtimes \\\n", "0 {'denv': {'py/object': 'palaestrai.types.simti... \n", "1 {'denv': {'py/object': 'palaestrai.types.simti... \n", "2 {'denv': {'py/object': 'palaestrai.types.simti... \n", "3 {'denv': {'py/object': 'palaestrai.types.simti... \n", "4 {'denv': {'py/object': 'palaestrai.types.simti... \n", ".. ... \n", "59 {'denv': {'py/object': 'palaestrai.types.simti... \n", "60 {'denv': {'py/object': 'palaestrai.types.simti... \n", "61 {'denv': {'py/object': 'palaestrai.types.simti... \n", "62 {'denv': {'py/object': 'palaestrai.types.simti... \n", "63 {'denv': {'py/object': 'palaestrai.types.simti... \n", "\n", " sensor_readings \\\n", "0 [] \n", "1 [] \n", "2 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "3 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "4 [{'py/object': 'palaestrai.agent.sensor_inform... \n", ".. ... \n", "59 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "60 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "61 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "62 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "63 [{'py/object': 'palaestrai.agent.sensor_inform... \n", "\n", " actuator_setpoints rewards objective \n", "0 [] 0.0 0.0 \n", "1 [] 0.0 0.0 \n", "2 [{'py/object': 'palaestrai.agent.actuator_info... 1.0 1.0 \n", "3 [{'py/object': 'palaestrai.agent.actuator_info... 1.0 1.0 \n", "4 [{'py/object': 'palaestrai.agent.actuator_info... 2.0 3.0 \n", ".. ... ... ... \n", "59 [{'py/object': 'palaestrai.agent.actuator_info... 7.0 118.0 \n", "60 [{'py/object': 'palaestrai.agent.actuator_info... 8.0 126.0 \n", "61 [{'py/object': 'palaestrai.agent.actuator_info... 8.0 126.0 \n", "62 [{'py/object': 'palaestrai.agent.actuator_info... 9.0 135.0 \n", "63 [{'py/object': 'palaestrai.agent.actuator_info... 9.0 135.0 \n", "\n", "[64 rows x 14 columns]" ] }, "execution_count": 80, "metadata": {}, "output_type": "execute_result" } ], "source": [ "muscle_actions.rewards = muscle_actions.rewards.apply(\n", " lambda x: unpack_reward(x)\n", ")\n", "muscle_actions" ] }, { "cell_type": "markdown", "id": "6b8c62e2", "metadata": {}, "source": [ "The table contains rewards, alternating, for both agents. You can see that from the `simtime_ticks` entry as well the `name` column. So let's plot them—it's easy now:" ] }, { "cell_type": "code", "execution_count": 81, "id": "ad47cbee", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 81, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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33zDb3/7Wz788ENAjSLk5eXRv39/ACZPnuzyfS+99BJpaWmsWrmCmWP7tNpxzdUudvz1L3/miquv5yfX3EDfron84Q9/4KuvvnJELWpra6mpqWHmzJn069cPgCFDhnTo7y5EIaYmqN7demxDURQWflLk+HOTyRpoy4RIpaUOij5QjwtvcFlSFIW3fzwMwFVjegTaMhdC2rGIj9FR/Oipw/Cd9d0dYc+ePcyfP58ffviB6upqrFZ1Mzl06BD5+fkd+qy33nqL559/npKSEurr6zGbzaSkpDjWN2/ezG233eb1M5555hkaGhr48ccfHXfmAFu2bGHFihUkJSW5vaekpMThWIwePbpDNgOMGTPG5c9btmxhzZo1jrQIqLLtzc3NNDY2kpaWxogRI1i5cqUjinP77bezYMEC6uvrWbVqFRMnTnS89+jRozz00EOsXLmSyspKLBYLjY2NHCrZA6Nb/yONGV3oOG4xWdi7ZxdXzlEdDastwzV+/HhWrFgBqJGim2++menTpzNt2jSmTp3KVVddRU5OTofPgRBFHC1uDUWbGhxPf7S5jE2HTjr+3GQ0B9gwIWIp+lC91jL6Q4+zXJY2HjpJSVUD8TE6Lhke3L0rpB0LjUbToXREMJk1axa9evXin//8J7m5uVitVoYOHdrhwsfvv/+eOXPmsHDhQqZPn05qaiqLFy/mmWeecbzGF7nzCRMm8Omnn/L222/zwAMPOJ6vr69n1qxZPPXUU27vcf5FmpiY2CG7Pb2nvr6ehQsX8pOf/MTttXbZ60mTJrFy5UpiY2OZOHEi6enpDBkyhNWrV7Nq1Sp+85vfON5z0003cezYMf785z/Tq1cvYmNjGT9+PMaGk652xCc4jo+3Kdi0tlM788orr3DXXXexdOlS3nrrLR566CG+/PJLzj777A6dAyGKqNjSemwroms0mnny850AjOudzroDx2k0Wjy9WxA6jj0NUng9tEnVvmOLVlw8LIfkuJhAW+ZCePzWDnGOHTvGrl27+Oc//8mECRMAWL16tWPdPvHSYnHdYAwGg9tz3333Hb169eLBBx90PNe2iHD48OF8/fXXLuH+towbN44777yTGTNmoNfrue+++wAYNWoU7733Hr1790av79x//lGjRrFr1y5HKsMTEydO5OWXX0av1zNjxgxAdTbefPNNdu/e7aivAFizZg1///vf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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "defender_actions = muscle_actions[muscle_actions.name == \"mighty_defender\"][\n", " [\"rewards\"]\n", "].rename(columns={\"rewards\": \"defender_rewards\"})\n", "attacker_actions = muscle_actions[muscle_actions.name == \"evil_attacker\"][\n", " [\"rewards\"]\n", "].rename(columns={\"rewards\": \"attacker_rewards\"})\n", "pd.concat([attacker_actions, defender_actions]).plot()" ] }, { "cell_type": "markdown", "id": "bf1d603f", "metadata": {}, "source": [ "## Conclusion\n", "\n", "This concludes our first tutorial. We hope you enjoyed the whole run. If you encountered any errors, head over to the [palaestrAI issue tracker at Gitlab](https://gitlab.com/arl2/palaestrai/-/issues) and let us know!" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.5" } }, "nbformat": 4, "nbformat_minor": 5 }