diff --git a/hbp_nrp_virtual_coach/doc/Makefile b/hbp_nrp_virtual_coach/doc/Makefile index cc83591d17def88914c783c923f5498caa87f166..13f23eeebe3a28f5649dfe98208c395ea9fc2f46 100644 --- a/hbp_nrp_virtual_coach/doc/Makefile +++ b/hbp_nrp_virtual_coach/doc/Makefile @@ -10,7 +10,7 @@ BUILDDIR = build # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source +ALLSPHINXOPTS = -t standalone -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source diff --git a/hbp_nrp_virtual_coach/doc/source/conf.py b/hbp_nrp_virtual_coach/doc/source/conf.py index 7134af96ff94c046058f2a4e6a508dd676360172..6fddafcb5b1edb76f7c561933f765b5bc6569bc1 100644 --- a/hbp_nrp_virtual_coach/doc/source/conf.py +++ b/hbp_nrp_virtual_coach/doc/source/conf.py @@ -42,6 +42,9 @@ apidoc_module_dir = '../../pynrp' # General information about the project. project = u'Virtual Coach' +# These files will be included in the whole docs and are omitted during standalone build +exclude_patterns.append('tutorials/index.rst') + # Output file base name for HTML help builder. htmlhelp_basename = 'pynrp_doc' diff --git a/hbp_nrp_virtual_coach/doc/source/developer_manual.rst b/hbp_nrp_virtual_coach/doc/source/developer_manual.rst new file mode 100644 index 0000000000000000000000000000000000000000..f8b9788b8b7056ac27d1790d086c59ee840b64ff --- /dev/null +++ b/hbp_nrp_virtual_coach/doc/source/developer_manual.rst @@ -0,0 +1,17 @@ +.. _virtual_coach_dev_space: + +.. sectionauthor:: Viktor Vorobev <vorobev@in.tum.de> + +.. seealso:: + + :ref:`User manual<virtual_coach_intro>` / + :ref:`Tutorials<virtual-coach-tutorial>` / + :ref:`Code API reference<virtual-coach-api>` + +Virtual Coach developer space +============================= + +.. toctree:: + :maxdepth: 2 + + python_api \ No newline at end of file diff --git a/hbp_nrp_virtual_coach/doc/source/index.rst b/hbp_nrp_virtual_coach/doc/source/index.rst index 35a3865992b8a0c1733a6e55133ad9c7bb9c82bb..1a6dcd25885460112beff4c1aa7d960ffa321d8e 100644 --- a/hbp_nrp_virtual_coach/doc/source/index.rst +++ b/hbp_nrp_virtual_coach/doc/source/index.rst @@ -5,12 +5,17 @@ Virtual Coach Welcome to the Virtual Coach documentation! -Contents: +.. include:: introduction.rst + +---------------------------------- + +In the :doc:`Tutorials section<tutorials>` you can find the information on how to get started with the Virtual Coach. + +.. rubric:: Contents: .. toctree:: :maxdepth: 2 - introduction - python_api - + tutorials + developer_manual diff --git a/hbp_nrp_virtual_coach/doc/source/introduction.rst b/hbp_nrp_virtual_coach/doc/source/introduction.rst index d77a6c1e36e834125ca22acbe927bc53b817fcfe..0032b80c050b9acd542ea778144944555a2d17d2 100644 --- a/hbp_nrp_virtual_coach/doc/source/introduction.rst +++ b/hbp_nrp_virtual_coach/doc/source/introduction.rst @@ -1,27 +1,19 @@ -Introduction -============ +.. _virtual_coach_intro: -The Virtual Coach is a Python API that allows you to run and interact with experiments by scripting them instead of having to use the Web Cockpit. It is especially ideal for running learning experiments, where usually one experiment has to be run multiple times, each time with a different parameterization, and where intermediate results have to be saved to compare the effectiveness of different parameters at the end. Scripting experimetns does not restrict the viusalization. While an experiment is running from the Virtual Coach, you may still open the frontend and visualize what is happening in your experiments. +.. sectionauthor:: Eloy Retamino <retamino@ugr.es> -Users now can launch experiments from the Virtual Coach, interact with the simulation by adding, deleting or editing Transfer Functions and State Machines as well as modify the Brain Model and the Neural Populations on the fly. Also, CSV data that is being saved during a simulation can be accessed from the Virtual Coach and you can then plot the data using your own plotting functions for example. Additionally, you can reuse the same reset functionality found in the Web Cockpit from the Virtual Coach, meaning that after certain events have occured (a collision for example), or after running a simulation for a certain amount of time you can either reset the robot pose, the brain model, the environment or reset the whole simulation. +.. This page is used in nrp-documentation -There is a necessary configuration file that must be copied from the user-scripts repository ($HBP/user-scripts/config_files/VirtualCoach/config.json) to the VirtualCoach repository in order for the Virtual Coach to run. You can either copy this file manually, or you can just run the configure_nrp script in the user-scripts to automatically copy it. +The Virtual Coach is a Python API that allows you to run and interact with experiments by scripting them instead of having to use the Web Frontend. It is especially ideal for running learning experiments, where usually one experiment has to be run multiple times, each time with a different parameterization, and where intermediate results have to be saved to compare the effectiveness of different parameters at the end. Scripting experimetns does not restrict the viusalization. While an experiment is running from the Virtual Coach, you may still open the frontend and visualize what is happening in your experiments. -There is a special alias for running the Virtual Coach. For this alias to work, $HBP/user-scripts/nrp_aliases has to be sourced in your bash.rc. Again, the configure_nrp script takes care of that automatically. The Virtual Coach alias is `cle-virtual-coach` and can be run in three different ways: +Users now can launch experiments from the Virtual Coach, interact with the simulation by adding, deleting or editing :term:`Transfer Functions<TF>` and State Machines as well as modify the Brain Model and the Neural Populations on the fly. Also, CSV data that is being saved during a simulation can be accessed from the Virtual Coach and you can then plot the data using your own plotting functions for example. Additionally, you can reuse the same reset functionality found in the Web Cockpit from the Virtual Coach, meaning that after certain events have occured (a collision for example), or after running a simulation for a certain amount of time you can either reset the robot pose, the brain model, the environment or reset the whole simulation. -1. **Launch a Jupyter Notebook session** +You can use developer's space for checking the :ref:`desciption of the API<virtual-coach-api>`, and if you have the local Virtual Coach repository you can check out the **VirtualCoach/examples** directory for some examples. Each example includes a **README** that may be useful to read before running it. Note that examples in the repository may be saved in a jupyter notebook as it makes it easier to run everything step-by-step and visualize results in place. - To launch a Jupyter Notebook session just run `cle-virtual-coach jupyter notebook` in a terminal. Of course, Jupyter Notebook has to be installed prior. +.. rubric:: Stand-alone installation -2. **Launch an interactive python interpreter session** +The Virtual Coach can be installed with pip independently of the rest of the NRP: - To launch an interactive python interpreter session just run `cle-virtual-coach python` in a terminal. - -3. **Launch a python script with arguments** - - To launch a python script `foo.py` with arguments `a b c` just run `cle-virtual-coach foo.py a b c`. - -This information is also available in the alias help `cle-virtual-coach -h`. - -In the next page you will find a desciption of the API, and if you have the local Virtual Coach repository you can check out the VirtualCoach/examples directory for some examples. Each example includes a README that may be useful to read before running it. Note that examples in the repository may be saved in a jupyter notebook as it makes it easier to run everything step-by-step and visualize results in place. +.. code-block:: bash + pip3 install pynrp diff --git a/hbp_nrp_virtual_coach/doc/source/python_api.rst b/hbp_nrp_virtual_coach/doc/source/python_api.rst index 745a4151aa798b0d51420ace83fda286e2b85d16..3898bfd8d4e0ae96afe5f8e7541da9001134b6f8 100644 --- a/hbp_nrp_virtual_coach/doc/source/python_api.rst +++ b/hbp_nrp_virtual_coach/doc/source/python_api.rst @@ -1,3 +1,13 @@ +.. _virtual-coach-api: + +.. sectionauthor:: Viktor Vorobev <vorobev@in.tum.de> + +.. seealso:: + + :ref:`User manual<virtual_coach_intro>` / + :ref:`Tutorials<virtual-coach-tutorial>` / + :ref:`Developer pages<virtual_coach_dev_space>` + Python developer API ==================== diff --git a/hbp_nrp_virtual_coach/doc/source/tutorials.rst b/hbp_nrp_virtual_coach/doc/source/tutorials.rst new file mode 100644 index 0000000000000000000000000000000000000000..e5f622ef4905a99efe8ab510c278d6be90871fc8 --- /dev/null +++ b/hbp_nrp_virtual_coach/doc/source/tutorials.rst @@ -0,0 +1,18 @@ +.. _virtual-coach-tutorials: + +.. sectionauthor:: Eloy Retamino <retamino@ugr.es> + +.. seealso:: + + :ref:`User manual<virtual_coach_intro>` / + :ref:`Code API reference<virtual-coach-api>` / + :ref:`Developer pages<virtual_coach_dev_space>` + +Virtual Coach Tutorials +======================= + +.. toctree:: + :maxdepth: 2 + + tutorials/launching_exp + tutorials/interacting_exp diff --git a/hbp_nrp_virtual_coach/doc/source/tutorials/img/experiment_workflow.png b/hbp_nrp_virtual_coach/doc/source/tutorials/img/experiment_workflow.png new file mode 100644 index 0000000000000000000000000000000000000000..6cb2fe55748d2bf8cff49ef8e4d01f278fa96929 Binary files /dev/null and b/hbp_nrp_virtual_coach/doc/source/tutorials/img/experiment_workflow.png differ diff --git a/hbp_nrp_virtual_coach/doc/source/tutorials/index.rst b/hbp_nrp_virtual_coach/doc/source/tutorials/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..40075cf6014a819d7886238e123537a359dea8d3 --- /dev/null +++ b/hbp_nrp_virtual_coach/doc/source/tutorials/index.rst @@ -0,0 +1,19 @@ +.. _virtual-coach-tutorial: + +.. sectionauthor:: Eloy Retamino <retamino@ugr.es> + +.. seealso:: + + :ref:`User manual<virtual_coach_intro>` / + :ref:`Code API reference<virtual-coach-api>` / + :ref:`Developer pages<virtual_coach_dev_space>` + +.. this page is included in the whole docs + +Virtual Coach Tutorial +====================== + +.. toctree:: + + launching_exp + interacting_exp diff --git a/hbp_nrp_virtual_coach/doc/source/tutorials/interacting_exp.rst b/hbp_nrp_virtual_coach/doc/source/tutorials/interacting_exp.rst new file mode 100644 index 0000000000000000000000000000000000000000..cdb44fe280a21394421ec7613f8877a9f31d6043 --- /dev/null +++ b/hbp_nrp_virtual_coach/doc/source/tutorials/interacting_exp.rst @@ -0,0 +1,236 @@ +.. _virtual-coach-tutorials-interact: + +.. sectionauthor:: Eloy Retamino <retamino@ugr.es> + +Interacting with an Experiment from the Virtual Coach +=============================================================== + +In the :ref:`previous section <virtual-coach-tutorials-launch>` we successfully launched a simulation of the Template Husky experiment. In this tutorial, we will interact with the simulation through the Virtual Coach. + +Getting and Setting Simulation States +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +When an experiment is launched, it is initially in the *paused* state. This means the experiment has to be explicitly started. In general, we can query the simulation state by calling: + +.. code-block:: python + + sim.get_state() + +The state of the simulation is returned as a string. In this case calling ``get_state()`` will return *paused*. The possible states we can set a simulation to are *paused*, *started* and *stopped*. We can alternatively start and pause the simulation by calling: + +.. code-block:: python + + sim.pause() + sim.start() + +Note that the timeout for a simulation is 15 minutes. + +Transfer Functions +^^^^^^^^^^^^^^^^^^ +From the Virtual Coach, we can view transfer functions, modify them, delete them, or add new ones. The transfer functions unique identifiers are their function names. To know the names of the transfer functions defined in an experiments, we can call: + +.. code-block:: python + + sim.print_transfer_functions() + +which would just print out the names of the transfer functions. In the case of the Template Husky experiment, this call will print out: *turn_around*, *csv_spike_monitor*, *all_neurons_spike_monitor*, *grab_image*, and *csv_joint_state_monitor*. To actually see the code of a transfer function, we can use the get_transfer_function call, which takes the transfer function name as a parameter and returns the code in a string. We will get the code of the turn-around transfer function and store it in a variable: + +.. code-block:: python + + turn_around_tf = sim.get_transfer_function('turn_around') + +If you're using a jupyter notebook, you can use the ``%load`` command to load the transfer function code in a cell. This will allow you to see the code syntax highlighted and properly indented and will make it easier to modify the functions: + +.. code-block:: python + + %load turn_around_tf + +This should load this function in a new cell in the jupyter notebook: + +.. code-block:: python + + import hbp_nrp_cle.tf_framework as nrp + from hbp_nrp_cle.robotsim.RobotInterface import Topic + import geometry_msgs.msg + @nrp.MapSpikeSink("output_neuron", nrp.brain.neurons[1], nrp.leaky_integrator_alpha) + @nrp.Neuron2Robot(Topic('/husky/husky/cmd_vel', geometry_msgs.msg.Twist)) + # Example TF: get output neuron voltage and output constant on robot actuator. You could do something with the voltage here and command the robot accordingly. + def turn_around(t, output_neuron): + voltage=output_neuron.voltage + return geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(0,0,0), + angular=geometry_msgs.msg.Vector3(0,0,5)) + +You can modify the code however you want and then save it as a string. Here we'll just increase the angular velocity by modifying the last line in the above code and replacing the number 5 with 10. We will save the modified code as a string in the variable *turn_around_tf*: + +.. code-block:: python + + turn_around_tf = """ + import hbp_nrp_cle.tf_framework as nrp + from hbp_nrp_cle.robotsim.RobotInterface import Topic + import geometry_msgs.msg + @nrp.MapSpikeSink("output_neuron", nrp.brain.neurons[1], nrp.leaky_integrator_alpha) + @nrp.Neuron2Robot(Topic('/husky/husky/cmd_vel', geometry_msgs.msg.Twist)) + # Example TF: get output neuron voltage and output constant on robot actuator. You could do something with the voltage here and command the robot accordingly. + def turn_around(t, output_neuron): + voltage=output_neuron.voltage + return geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(0,0,0), + angular=geometry_msgs.msg.Vector3(0,0,10)) + """ + +This modified transfer function will only make the robot spin faster in this experiment. If you open your frontend web cockpit and join the running experiment, you will see the robot spinning faster once we actually apply the transfer function. To apply the transfer function we use the call edit_transfer_function which takes as parameters the name of the transfer function to be modified and the modified code. + +.. code-block:: python + + sim.edit_transfer_function('turn_around', turn_around_tf) + +The Virtual Coach will maintain the simulation state after setting the transfer function. This means that if the simulation was running, the Virtual Coach will modify the transfer function and then automatically start the simulation again. + +As a user you can also delete transfer functions from the Virtual Coach. You just need to provide the name of the transfer function and use it in the following call: + +.. code-block:: python + + sim.delete_transfer_function('turn_around') + +This will delete the turn_around transfer function we just modified. If you have a frontend web cockpit joined on your simulation, you will notice that the robot stopped spinning since the transfer function responsible for that behavior has been deleted. Note that deletion and addition of transfer functions are not reflected in the frontend. If you want more proof that the transfer function has been deleted, you can revisit the print_transfer_functions call and make sure that it doesn't print out turn_around. + +We can also add new transfer functions. For this we only need to provide the transfer function code as a string parameter to the add_transfer_function function. We don't have to provide a name since the name will just be the function's name. Remember that transfer functions definition names have to be unique, so duplicate function names will result in errors. Here we'll create three transfer functions that store Spike, Joint and Robot positions into csv files. + +.. code-block:: python + + csv_spike_monitor = """@nrp.MapCSVRecorder("recorder", filename="all_spikes.csv", headers=["id", "time"]) + @nrp.MapSpikeSink("record_neurons", nrp.brain.record, nrp.spike_recorder) + @nrp.Neuron2Robot(Topic('/monitor/spike_recorder', cle_ros_msgs.msg.SpikeEvent)) + def csv_spike_monitor(t, recorder, record_neurons): + for i in range(0, len(record_neurons.times)): + recorder.record_entry( + record_neurons.times[i][0], + record_neurons.times[i][1] + )""" + + sim.add_transfer_function(csv_spike_monitor) + +.. code-block:: python + + csv_joint_state_monitor = """@nrp.MapRobotSubscriber("joint_state", Topic('/husky/joint_states', sensor_msgs.msg.JointState)) + @nrp.MapCSVRecorder("recorder", filename="all_joints_positions.csv", headers=["Name", "time", "Position"]) + def csv_joint_state_monitor(t, joint_state, recorder): + if not isinstance(joint_state.value, type(None)): + for i in range(0, len(joint_state.value.name)): + recorder.record_entry(joint_state.value.name[i], t, joint_state.value.position[i])""" + + sim.add_transfer_function(csv_joint_state_monitor) + +.. code-block:: python + + csv_robot_position = """@nrp.MapCSVRecorder("recorder", filename="robot_position.csv", headers=["x", "y", "z"]) + @nrp.MapRobotSubscriber("position", Topic('/gazebo/model_states', gazebo_msgs.msg.ModelStates)) + @nrp.MapVariable("robot_index", global_key="robot_index", initial_value=None) + @nrp.Robot2Neuron() + def csv_robot_position(t, position, recorder, robot_index): + if not isinstance(position.value, type(None)): + + # determine if previously set robot index has changed + if robot_index.value is not None: + + # if the value is invalid, reset the index below + if robot_index.value >= len(position.value.name) or\ + position.value.name[robot_index.value] != 'husky': + robot_index.value = None + + # robot index is invalid, find and set it + if robot_index.value is None: + + # 'husky' is the bodyModel declared in the bibi, if not found raise error + robot_index.value = position.value.name.index('husky') + + # record the current robot position + recorder.record_entry(position.value.pose[robot_index.value].position.x, + position.value.pose[robot_index.value].position.y, + position.value.pose[robot_index.value].position.z)""" + + sim.add_transfer_function(csv_robot_position) + + +Those transfer functions will log the simulation time to the log console every two seconds. + + +Getting CSV Data +^^^^^^^^^^^^^^^^ + +With the transfer functions that we wrote, we can access all csv data from the Virtual Coach and plot or analyze the data. To know what kind of data is being saved to csv files in an experiment, you can print out the names of the csv files first using this call: + +.. code-block:: python + + vc.print_csv_last_run_files(exp_id) + +In the case of the Template Husky experiment, this will print out *all_spikes.csv* and *all_joints_positions.csv* and *robot_position.csv*. We can now get the data from any one of these files. Note that these files will be populated only if a simulation has been running. Here we will get and print out the Spike data: + +.. code-block:: python + + spikes = vc.print_csv_last_run_file(exp_id, 'all_spikes.csv') + print(spikes) + [[u'id', u'time', u'Simulation_reset'], + [u'3.0', u'0.10000000000000001', u'RESET'], + [u'4.0', u'2.6000000000000001', u''], + [u'3.0', u'57.200000000000003', u'']] + +In the code snippet above you can notice the additional *Simulation_reset* column which automatically keeps track of *reset* events. + +We can also write our own custom functions to plot the data we got. The following is a custom function that will plot each spike from the csv file as a blue dot. Note also that the first line in the csv data is a header that need to be accounted for when plotting. + +.. code-block:: python + + from StringIO import StringIO + import pandas as pd + import matplotlib.pyplot as plt + + spikes_df = pd.read_csv(StringIO(spikes), sep=",") + spikes_df.plot.scatter('time','id') + plt.show() + +State Machines +^^^^^^^^^^^^^^ +Through the Virtual Coach, users can interact with the simulation state machines the same way they can with the transfer functions. Currently we have only one experiment that contains a state machine. Let's stop our current simulation and start it and see how we can interact with the state machines. + +.. code-block:: python + + sim.stop() + exp_id = vc.clone_experiment_to_storage('ScreenSwitchingHuskyExperiment') + sim = vc.launch_experiment(exp_id) + +After the experiment has been started, we can retrieve the names of the defined state machines. + +.. code-block:: python + + sim.print_state_machines() + +This call should print out *HuskyAwareScreenControlling*. To retrieve the code of the state machine, we will have to use its name we just got. + +.. code-block:: python + + sm = sim.get_state_machine('HuskyAwareScreenControlling') + +Since state machines are also python scripts, we can load them in jupyter notebooks with the ``%load`` command like we did with the transfer functions. Additionally, we can also edit and delete them, or add new ones, exactly like we interact with transfer functions. Below are the calls for editing, deleting and adding state machines. + +.. code-block:: python + + sim.edit_state_machine(state_machine_name, state_machine_code) + sim.delete_state_machine(state_machine_name) + sim.add_state_machine(state_machine_name, state_machine_code) + +The only difference between interacting with state machines and transfer functions is that the state machines' are not the python function names. Therefore, when adding a new state machine, the user has to explicitly give it a name. + +Reset Functionality +^^^^^^^^^^^^^^^^^^^ + +It is also possible to reset certain aspects of the simulation from the Virtual Coach, exactly as it is possible from the web cockpit. There are four **reset types** possible from the Virtual Coach: *Robot Frame*, *Environment*, *Brain*, and the *Full Simulation*. You can reset all simulation aspects with the same call: + + +.. code-block:: python + + sim.reset('robot_pose') + sim.reset('world') + sim.reset('brain') + sim.reset('full') + +If you want to look at more concrete example experiments run from the Virtual Coach, you can check out the **hbp_nrp_virtual_coach/examples** directory. + diff --git a/hbp_nrp_virtual_coach/doc/source/tutorials/launching_exp.rst b/hbp_nrp_virtual_coach/doc/source/tutorials/launching_exp.rst new file mode 100644 index 0000000000000000000000000000000000000000..1de0fe99bd8f9a26aa43d976a18d7d963fe91b51 --- /dev/null +++ b/hbp_nrp_virtual_coach/doc/source/tutorials/launching_exp.rst @@ -0,0 +1,69 @@ +.. _virtual-coach-tutorials-launch: + +.. sectionauthor:: Eloy Retamino <retamino@ugr.es> + +Launching an Experiment from the Virtual Coach +======================================================== + +Starting the Virtual Coach +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +There is a special alias for running the Virtual Coach. For this alias to work, :code:`$HBP/user-scripts/nrp_aliases` has to be sourced in your *bash.rc*. The ``configure_nrp`` script takes care of that automatically. The Virtual Coach alias is :code:`cle-virtual-coach` and can be run in three different ways: + +There are different ways to start a Virtual Coach instance. With a local :abbr:`NRP (Neurorobotics Platform)` install you can use the alias :code:`cle-virtual-coach` in three different ways: + +1. **Launch a Jupyter Notebook session** + + To launch a Jupyter Notebook session just run :code:`cle-virtual-coach jupyter notebook` in a terminal. Of course, Jupyter Notebook has to be installed prior. + +2. **Launch an interactive python interpreter session** + + To launch an interactive python interpreter session just run :code:`cle-virtual-coach python` in a terminal. + +3. **Launch a python script with arguments** + + To launch a python script *foo.py* with arguments *a b c* just run :code:`cle-virtual-coach foo.py a b c`. + +This information is also available in the alias help :code:`cle-virtual-coach -h`. + +Launching a Simulation +^^^^^^^^^^^^^^^^^^^^^^ +The first thing we need to do is to import the Virtual Coach and create a VirtualCoach instance connected to an NRP server. + +.. code-block:: python + + from pynrp.virtual_coach import VirtualCoach + vc = VirtualCoach(environment='http://localhost:9000', storage_username='nrpuser', storage_password='password') + +Here we chose the local machine as the NRP server. The Virtual Coach can connect to NRP servers running in other locations by setting the *environment* parameter to the proper URL. For example, it is possible to connect to the NRP server running at *148.187.97.37* by executing this command: + +.. code-block:: python + + vc = VirtualCoach('http://148.187.97.37', oidc_username='<your-hbp-username>', oidc_password='<your-hbp-password>') + +Notice that parameters *storage_username* and *storage_password* are replaced with *oidc_username* and *oidc_password*. The latter must be used when :term:`OIDC` authentication is required, the former are used otherwise. + +Once we created a VirtualCoach instance, we can use it to check out the current state of our environment. We can see a list of the available experiments to run, a list of the available servers to run experiments on, and a list of the currently running experiments. + +.. code-block:: python + + vc.print_templates() + vc.print_available_servers() + vc.print_running_experiments() + +After making sure our experiments exist and enough resources are available, we can attempt to launch an experiment. In this next section we will launch the Template Husky experiment. We first need to clone the experiment in our storage. To launch a specific experiment, we need to specify its configuration name, which we can get from the cloned experiment list. + +.. code-block:: python + + exp_id = vc.clone_experiment_to_storage('ExDTemplateHusky') + vc.print_cloned_experiments() + sim = vc.launch_experiment(exp_id) + + +Launching an experiment can take some time and once it's been successfully launched, we'll get a `Simulation Successfully Created` log. + +We can also make sure that the experiment has been launched by querying the Virtual Coach for currently running experiments. + +---------------------------------- + +Read more about the **interaction with the experiment throught the Virtual Coach** in the :ref:`following tutorial <virtual-coach-tutorials-interact>`. \ No newline at end of file