diff --git a/examples/Basics.ipynb b/examples/Basics.ipynb new file mode 100644 index 0000000..ff5b4b3 --- /dev/null +++ b/examples/Basics.ipynb @@ -0,0 +1,886 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "if(window['d3'] === undefined ||\n", + " window['Nyaplot'] === undefined){\n", + " var path = {\"d3\":\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min\",\"downloadable\":\"http://cdn.rawgit.com/domitry/d3-downloadable/master/d3-downloadable\"};\n", + "\n", + "\n", + "\n", + " var shim = {\"d3\":{\"exports\":\"d3\"},\"downloadable\":{\"exports\":\"downloadable\"}};\n", + "\n", + " require.config({paths: path, shim:shim});\n", + "\n", + "\n", + "require(['d3'], function(d3){window['d3']=d3;console.log('finished loading d3');require(['downloadable'], function(downloadable){window['downloadable']=downloadable;console.log('finished loading downloadable');\n", + "\n", + "\tvar script = d3.select(\"head\")\n", + "\t .append(\"script\")\n", + "\t .attr(\"src\", \"http://cdn.rawgit.com/domitry/Nyaplotjs/master/release/nyaplot.js\")\n", + "\t .attr(\"async\", true);\n", + "\n", + "\tscript[0][0].onload = script[0][0].onreadystatechange = function(){\n", + "\n", + "\n", + "\t var event = document.createEvent(\"HTMLEvents\");\n", + "\t event.initEvent(\"load_nyaplot\",false,false);\n", + "\t window.dispatchEvent(event);\n", + "\t console.log('Finished loading Nyaplotjs');\n", + "\n", + "\t};\n", + "\n", + "\n", + "});});\n", + "}\n" + ], + "text/plain": [ + "\"if(window['d3'] === undefined ||\\n window['Nyaplot'] === undefined){\\n var path = {\\\"d3\\\":\\\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min\\\",\\\"downloadable\\\":\\\"http://cdn.rawgit.com/domitry/d3-downloadable/master/d3-downloadable\\\"};\\n\\n\\n\\n var shim = {\\\"d3\\\":{\\\"exports\\\":\\\"d3\\\"},\\\"downloadable\\\":{\\\"exports\\\":\\\"downloadable\\\"}};\\n\\n require.config({paths: path, shim:shim});\\n\\n\\nrequire(['d3'], function(d3){window['d3']=d3;console.log('finished loading d3');require(['downloadable'], function(downloadable){window['downloadable']=downloadable;console.log('finished loading downloadable');\\n\\n\\tvar script = d3.select(\\\"head\\\")\\n\\t .append(\\\"script\\\")\\n\\t .attr(\\\"src\\\", \\\"http://cdn.rawgit.com/domitry/Nyaplotjs/master/release/nyaplot.js\\\")\\n\\t .attr(\\\"async\\\", true);\\n\\n\\tscript[0][0].onload = script[0][0].onreadystatechange = function(){\\n\\n\\n\\t var event = document.createEvent(\\\"HTMLEvents\\\");\\n\\t event.initEvent(\\\"load_nyaplot\\\",false,false);\\n\\t window.dispatchEvent(event);\\n\\t console.log('Finished loading Nyaplotjs');\\n\\n\\t};\\n\\n\\n});});\\n}\\n\"" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + " Trajectory following with ARIEL (2a59a184332bc184c7e78f96545bb70a5d45ec46d5963e79355a7ba8dd2c3f1c) \n", + "\n", + "\n", + "\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "
NameModelPorts
aceinna_imu_taskimu_aceinna_openimu::Taskio_status_port , imu_sensors_samples_port , state_port , pose_samples_port , status_samples_port , io_read_listener_port , io_raw_out_port , magnetic_info_port , timestamp_estimator_status_port , acceleration_samples_port , io_write_listener_port
aft_camera_taskcamera_rtsp_gstreamer::ReceiverTaskstate_port
ais_0183_tasknmea0183::AISTaskio_raw_out_port , state_port , voyages_information_port , io_status_port , ais_stats_port , positions_port , io_write_listener_port , io_read_listener_port , vessels_information_port , nmea_stats_port
body_pose_transformation_taskwetpaint_common::BodyPoseTransformationTaskstate_port , transformer_stream_aligner_status_port , transformer_status_port , body_pose_port
camera_compositor_taskwetpaint_camera_compositor::Taskstate_port
camera_streaming_taskvideo_streamer_webrtc::StreamerTaskstate_port
can_boat_taskcanbus::Taskpower_cube_starboard_port , state_port , stats_port , rudder_motor_port , smart_shunt_port , power_cube_port_port
can_n2k_taskcanbus::Taskstate_port , nmea2000_port , stats_port
clutch_control_taskwetpaint_live::RudderClutchControlstate_port , actual_cmd_port , steering_enable_port
cmd_force_to_speed_taskusv_control::ForceToSpeedTaskstate_port , forward_input_port , rotation_port
cmd_speed_to_force_taskusv_control::SpeedToForceTaskstate_port , thrust_port , forward_input_port
controldev_websocket_taskcontroldev_websocket::Taskstatistics_port , raw_command_port , state_port
depth_sounder_tasknmea2000::AirmarDST800Taskstate_port , depth_samples_port , speed_samples_port , temperature_samples_port
forward_camera_taskcamera_rtsp_gstreamer::ReceiverTaskstate_port
forwarder_taskusv_control::ForwarderTaskstate_port , out_port
gpio_depth_sensor_enable_tasklinux_gpios::Task
gpio_propulsion_enable_tasklinux_gpios::Task
gpio_steering_enable_tasklinux_gpios::Task
heading_control_taskusv_control::PIDHeadingTaskcmd_out_port , controller_state_port , state_port
nmea2000_tasknmea2000::CANTaskais_port , tank_level_starboard_port , depth_sounder_port , can_out_port , state_port , device_information_port , resolved_devices_port , messages_port , tank_level_port_port
port_camera_taskcamera_rtsp_gstreamer::ReceiverTaskstate_port
power_cube_port_taskpower_whisperpower::DCPowerCubeTaskfull_status_port , ac_generator_status_port , dc_output_status_port , ac_grid_status_port , state_port , can_out_port
power_cube_starboard_taskpower_whisperpower::DCPowerCubeTaskfull_status_port , dc_output_status_port , ac_generator_status_port , can_out_port , ac_grid_status_port , state_port
propulsion_demultiplexer_taskwetpaint_live::PropulsionMultiplexerstate_port , multiplexed_out_port
propulsion_modbus_multiplexer_taskwetpaint_live::MotorsMultiplexerio_raw_out_port , state_port , starboard_raw_out_port , port_raw_out_port , io_status_port , io_write_listener_port , io_read_listener_port
propulsion_multiplexer_taskwetpaint_live::PropulsionDemultiplexerport_out_port , state_port , starboard_out_port
propulsion_port_controller_taskmotors_weg_cvw300::Taskfault_state_port , io_write_listener_port , temperatures_port , io_status_port , joint_samples_port , state_port , io_read_listener_port , io_raw_out_port , inverter_state_port
propulsion_safety_gpio_taskwetpaint_live::SafetyStatusGPIOHandlerTaskstate_port , gpio_out_port
propulsion_scheduler_taskslave_scheduler::OrderedSchedulingTaskstate_port
propulsion_starboard_controller_taskmotors_weg_cvw300::Tasktemperatures_port , io_write_listener_port , io_status_port , io_raw_out_port , io_read_listener_port , joint_samples_port , inverter_state_port , state_port , fault_state_port
raw_to_actuator_commands_taskusv_control::RawToActuatorCommandsTaskcontroller_state_port , state_port , rotation_cmd_port , rudder_angle_cmd_port
rudder_actuator_to_angle_taskusv_control::RudderActuatorToAngleTaskstate_port , rudder_position_samples_port
rudder_analog_to_position_taskwetpaint_live::RudderLinearActuatorPositionTaskposition_samples_port , state_port
rudder_angle_to_actuator_taskusv_control::RudderAngleToActuatorTaskstate_port , actuator_cmd_port
rudder_control_taskmotors_roboteq_canopen::Taskstate_port , joint_samples_port , controller_status_port , can_out_port , analog_inputs_port
rudder_pid_taskmotor_controller::PIDTaskstate_port , pid_states_port , out_command_port
rudder_pid_course_change_control_taskusv_control::RudderPIDCourseChangeControlTaskstate_port , controller_state_port , cmd_out_port , corrected_course_change_cmd_port
smart_shunt_taskpower_whisperpower::SmartShuntTaskcan_out_port , state_port , full_status_port , battery_status_port , battery_dc_output_status_port
starboard_camera_taskcamera_rtsp_gstreamer::ReceiverTaskstate_port
status_speed_to_force_taskusv_control::SpeedToForceTaskthrust_port , forward_input_port , state_port
tank_level_port_tasknmea2000::FluidLevelTaskstate_port , level_out_port
tank_level_starboard_tasknmea2000::FluidLevelTaskstate_port , level_out_port
telemetry_usv_taskcomms_wetpaint::USVTaskdesired_safety_status_port , stream_stats_port , control_station_common_status_port , io_read_listener_port , io_raw_out_port , state_port , io_status_port , io_write_listener_port
thruster_mapping_taskusv_control::DifferentialThrusterMappingTaskcmd_out_port , controller_state_port , state_port
trajectory_follower_taskusv_control::XYYawTrajectoryFollowerTaskstate_port , controller_state_port , cmd_out_port
transformer_broadcaster_tasktransformer::Taskstate_port , configuration_state_port
ublox_gps_taskgps_ublox::Taskgps_solution_port , io_read_listener_port , pose_samples_port , rf_info_port , io_write_listener_port , state_port , signal_info_port , io_raw_out_port , satellite_info_port , io_status_port
velocity_control_taskusv_control::PIDVelocityTaskcontroller_state_port , state_port , cmd_out_port
wave_filter_taskusv_control::WaveFilterTaskout_port , state_port
wind_sensor_taskwind_lcj_cv7::Task
\n" + ], + "text/plain": [ + "#" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "require \"vega\"\n", + "require \"syskit/log/dsl\"\n", + "require \"syskit/log/daru\"\n", + "extend Syskit::Log::DSL\n", + "\n", + "# Select a dataset by ID. Metadata queries can also be used, as e.g.\n", + "# dataset_select({ \"roby:time\" => /202011/ })\n", + "# \n", + "# You usually want this to be the last instruction in a cell, as it\n", + "# displays summary information about the dataset\n", + "dataset_select \"2a59a184332bc184c7e78f96545bb70a5d45ec46d5963e79355a7ba8dd2c3f1c\"" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[2020-11-18 16:15:32.2885 -0300, 2020-11-18 16:27:49.497145 -0300]" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Restrict the processing to the interval during which this task was running.\n", + "# This spawns a IRuby selection widget to select the right unit.\n", + "interval_select roby.Seabots.Tasks.Missions.USVTransit" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "Seabots::Tasks::Missions::USVTransit\n", + "\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + "\n", + "
IDStartStopStart (relative)Stop (relative)
1802020-11-18 15:15:31 -03002020-11-18 15:17:43 -0300-3601.157769-3469.096664
2322020-11-18 15:18:12 -03002020-11-18 15:43:23 -0300-3439.968913-1928.701197
3272020-11-18 15:43:58 -03002020-11-18 16:02:15 -0300-1893.992964-796.605589
3802020-11-18 16:02:36 -03002020-11-18 16:15:14 -0300-775.961856-18.00742
4552020-11-18 16:15:32 -03002020-11-18 16:27:49 -03000.0737.208645
5192020-11-18 16:28:18 -03002020-11-18 16:38:23 -0300766.4379291370.923213
5752020-11-18 16:43:10 -03002020-11-18 16:48:28 -03001657.794331976.074924
\n" + ], + "text/plain": [ + "#" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Alternatively, use summarize to get information about the tasks that have run and select one by its ID\n", + "summarize roby.Seabots.Tasks.Missions.USVTransit" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[2020-11-18 16:28:38.726429 -0300, 2020-11-18 16:29:38.726429 -0300]" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "interval_select roby.Seabots.Tasks.Missions.USVTransit.by_id(519)\n", + "# Pick samples at least separated by that many seconds\n", + "interval_sample_every seconds: 0.1\n", + "# Shift the start of the interval by that many seconds (can be positive or negative)\n", + "interval_shift_start 20\n", + "# End offset w.r.t. the start of the interval\n", + "interval_shift_end 60" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# Convert data stream data into a Daru frame. The first stream is the \"clock\"\n", + "# stream, that is the returned frame has one row per sample in this stream\n", + "frame = to_daru_frame body_pose_transformation_task.body_pose_port,\n", + " velocity_control_task.controller_state_port do |pose, control|\n", + " \n", + " # In this block, one defines one colum per scalar value extracted from the data streams\n", + " \n", + " # Time fields must return microseconds. They are automatically made relative to the\n", + " # chosen interval's start time. The fields are from the raw typelib values (as reported\n", + " # )\n", + " pose.add_time_field(\"time\") { |rbs| rbs.time.microseconds }\n", + " pose.add(\"x\") { |rbs| rbs.position.data[0] }\n", + " control.add(\"P\") { |state| state.forward_velocity.P }\n", + "\n", + " # .transform allows to get a Ruby value and arbitrarily transform it\n", + " pose.add(\"yaw\") { |rbs| rbs.orientation.transform { |q| q.yaw } }\n", + "end\n", + "\n", + "# You can do column-wide conversion or statistics using the Daru API.\n", + "# See https://www.rubydoc.info/gems/daru/0.3\n", + "frame[\"yaw\"] = frame[\"yaw\"] * 180 / Math::PI\n", + "\n", + "# nil is to avoid displaying the frame\n", + "nil" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n" + ], + "text/plain": [ + "
\n", + "\n" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Now plot. The vega_simple_plot helper allows to do quick plots\n", + "vega_simple_plot frame, x: \"time\", y: [\"x\", \"yaw\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n" + ], + "text/plain": [ + "
\n", + "\n" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# See https://github.com/ankane/vega for the whole vega-lite API\n", + "#\n", + "# The DSL API does have Vega-specific helpers to simplify the task though. vega_simple_view\n", + "# creates a data-less view to do x/y plots.\n", + "\n", + "vega = daru_to_vega(frame)\n", + "view = vega_simple_view x: \"time\", y: { repeat: \"repeat\" }\n", + "Vega.lite.data(vega).repeat(%w[x yaw]).spec(view)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n" + ], + "text/plain": [ + "
\n", + "\n" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# This displays the tasks of a given type, restricted\n", + "# to the current interval (so, here, only one)\n", + "roby_task_timeline roby.Seabots.Tasks.Missions.USVTransit" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n" + ], + "text/plain": [ + "
\n", + "\n" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Let's plot the transition between two missions\n", + "tasks = roby.Seabots.Tasks.Missions.USVTransit.each_task.to_a\n", + "stop1 = tasks[1].stop_event.first.time\n", + "start2 = tasks[2].start_event.first.time\n", + "interval_select stop1, start2\n", + "interval_grow 30\n", + "roby_task_timeline roby.Seabots.Tasks.Missions.USVTransit" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n" + ], + "text/plain": [ + "
\n", + "\n" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Changing the interval does not re-generate the data frame, create a new one\n", + "frame2 = to_daru_frame body_pose_transformation_task.body_pose_port do |pose, control|\n", + " pose.add_time_field(\"time\") { |rbs| rbs.time.microseconds }\n", + " pose.add(\"x\") { |rbs| rbs.position.data[0] }\n", + " pose.add(\"yaw\") { |rbs| rbs.orientation.transform { |q| q.yaw } }\n", + "end\n", + "vega2 = daru_to_vega frame2\n", + "\n", + "# This time, let's mark the data with what task was running when, to visualize the transition\n", + "roby_vega_mark_tasks(\"task\", vega2, roby.Seabots.Tasks.Missions.USVTransit, time_field: \"time\")\n", + "\n", + "# And display again, this time using the new field (\"task\") for coloring\n", + "view = vega_simple_view x: \"time\", y: { repeat: \"repeat\" }, color: { field: \"task\" }\n", + "Vega.lite.data(vega2).repeat(%w[x yaw]).spec(view)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Ruby 2.7.1", + "language": "ruby", + "name": "ruby" + }, + "language_info": { + "file_extension": ".rb", + "mimetype": "application/x-ruby", + "name": "ruby", + "version": "2.7.1" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +}