From bf9abcfdfdeb69d8b70e64ee6aafe18e06dab89a Mon Sep 17 00:00:00 2001 From: jaseg Date: Thu, 25 Mar 2021 17:25:03 +0100 Subject: Accelerometer measurements: Update notebook with latest, more accurate data --- .../Accelerometer Data Analysis.ipynb | 1740 +++++++++++++++++--- .../sensor-analysis/fig-acc-theory-meas-run50.pdf | Bin 0 -> 17415 bytes prototype/sensor-analysis/fig-acc-theory-meas.pdf | Bin 0 -> 18126 bytes .../fig-acc-trace-stacked-run50.pdf | Bin 0 -> 67959 bytes .../sensor-analysis/fig-acc-trace-steps-run50.pdf | Bin 0 -> 103833 bytes .../sensor-analysis/fig-acc-trace-steps-run52.pdf | Bin 0 -> 83704 bytes prototype/sensor-analysis/fig-comms-delays.pdf | Bin 0 -> 13791 bytes prototype/sensor-analysis/test_run.sqlite3 | Bin 4272128 -> 12140544 bytes 8 files changed, 1541 insertions(+), 199 deletions(-) create mode 100644 prototype/sensor-analysis/fig-acc-theory-meas-run50.pdf create mode 100644 prototype/sensor-analysis/fig-acc-theory-meas.pdf create mode 100644 prototype/sensor-analysis/fig-acc-trace-stacked-run50.pdf create mode 100644 prototype/sensor-analysis/fig-acc-trace-steps-run50.pdf create mode 100644 prototype/sensor-analysis/fig-acc-trace-steps-run52.pdf create mode 100644 prototype/sensor-analysis/fig-comms-delays.pdf diff --git a/prototype/sensor-analysis/Accelerometer Data Analysis.ipynb b/prototype/sensor-analysis/Accelerometer Data Analysis.ipynb index 72f13c8..bc59667 100644 --- a/prototype/sensor-analysis/Accelerometer Data Analysis.ipynb +++ b/prototype/sensor-analysis/Accelerometer Data Analysis.ipynb @@ -61,7 +61,7 @@ }, { "cell_type": "code", - "execution_count": 83, + "execution_count": 97, "metadata": { "scrolled": false }, @@ -1058,13 +1058,16 @@ " seq, *data, _crc = struct.unpack('open comm proxy.\n", + " ws_proxy.onopen();\n", + "\n", + " fig.parent_element = element;\n", + " fig.cell_info = mpl.find_output_cell(\"
\");\n", + " if (!fig.cell_info) {\n", + " console.error('Failed to find cell for figure', id, fig);\n", + " return;\n", + " }\n", + " fig.cell_info[0].output_area.element.on(\n", + " 'cleared',\n", + " { fig: fig },\n", + " fig._remove_fig_handler\n", + " );\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_close = function (fig, msg) {\n", + " var width = fig.canvas.width / fig.ratio;\n", + " fig.cell_info[0].output_area.element.off(\n", + " 'cleared',\n", + " fig._remove_fig_handler\n", + " );\n", + " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", + "\n", + " // Update the output cell to use the data from the current canvas.\n", + " fig.push_to_output();\n", + " var dataURL = fig.canvas.toDataURL();\n", + " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", + " // the notebook keyboard shortcuts fail.\n", + " IPython.keyboard_manager.enable();\n", + " fig.parent_element.innerHTML =\n", + " '';\n", + " fig.close_ws(fig, msg);\n", + "};\n", + "\n", + "mpl.figure.prototype.close_ws = function (fig, msg) {\n", + " fig.send_message('closing', msg);\n", + " // fig.ws.close()\n", + "};\n", + "\n", + "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", + " // Turn the data on the canvas into data in the output cell.\n", + " var width = this.canvas.width / this.ratio;\n", + " var dataURL = this.canvas.toDataURL();\n", + " this.cell_info[1]['text/html'] =\n", + " '';\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Tell IPython that the notebook contents must change.\n", + " IPython.notebook.set_dirty(true);\n", + " this.send_message('ack', {});\n", + " var fig = this;\n", + " // Wait a second, then push the new image to the DOM so\n", + " // that it is saved nicely (might be nice to debounce this).\n", + " setTimeout(function () {\n", + " fig.push_to_output();\n", + " }, 1000);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'btn-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " var button;\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " continue;\n", + " }\n", + "\n", + " button = fig.buttons[name] = document.createElement('button');\n", + " button.classList = 'btn btn-default';\n", + " button.href = '#';\n", + " button.title = name;\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message pull-right';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = document.createElement('div');\n", + " buttongrp.classList = 'btn-group inline pull-right';\n", + " button = document.createElement('button');\n", + " button.classList = 'btn btn-mini btn-primary';\n", + " button.href = '#';\n", + " button.title = 'Stop Interaction';\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', function (_evt) {\n", + " fig.handle_close(fig, {});\n", + " });\n", + " button.addEventListener(\n", + " 'mouseover',\n", + " on_mouseover_closure('Stop Interaction')\n", + " );\n", + " buttongrp.appendChild(button);\n", + " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", + " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", + "};\n", + "\n", + "mpl.figure.prototype._remove_fig_handler = function (event) {\n", + " var fig = event.data.fig;\n", + " if (event.target !== this) {\n", + " // Ignore bubbled events from children.\n", + " return;\n", + " }\n", + " fig.close_ws(fig, {});\n", + "};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (el) {\n", + " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (el) {\n", + " // this is important to make the div 'focusable\n", + " el.setAttribute('tabindex', 0);\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " } else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager) {\n", + " manager = IPython.keyboard_manager;\n", + " }\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which === 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " fig.ondownload(fig, null);\n", + "};\n", + "\n", + "mpl.find_output_cell = function (html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i = 0; i < ncells; i++) {\n", + " var cell = cells[i];\n", + " if (cell.cell_type === 'code') {\n", + " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", + " var data = cell.output_area.outputs[j];\n", + " if (data.data) {\n", + " // IPython >= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] === html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "};\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel !== null) {\n", + " IPython.notebook.kernel.comm_manager.register_target(\n", + " 'matplotlib',\n", + " mpl.mpl_figure_comm\n", + " );\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Found sensor offset: -3.59 g / -35.21 m/s^2\n", + "Found sensor scale: -0.014\n", + "\n", + "Centrifugal acceleration at 1.58 Hz:\n", + " Theory: 0.55 g / 5.42 m/s^2\n", + " Measurement: 0.51 g / 5.028966965088801 m/s^2\n", + " Rel. Error: 7.78 %\n", + " Abs. Error: 0.04 g / 0.39 m/s^2\n", + "\n", + "Centrifugal acceleration at 2.11 Hz:\n", + " Theory: 0.99 g / 9.67 m/s^2\n", + " Measurement: 0.93 g / 9.162411313131324 m/s^2\n", + " Rel. Error: 5.51 %\n", + " Abs. Error: 0.05 g / 0.50 m/s^2\n", + "\n", + "Centrifugal acceleration at 2.85 Hz:\n", + " Theory: 1.80 g / 17.64 m/s^2\n", + " Measurement: 1.75 g / 17.17632651666313 m/s^2\n", + " Rel. Error: 2.68 %\n", + " Abs. Error: 0.05 g / 0.46 m/s^2\n", + "\n", + "Centrifugal acceleration at 3.30 Hz:\n", + " Theory: 2.41 g / 23.65 m/s^2\n", + " Measurement: 2.38 g / 23.327857994031824 m/s^2\n", + " Rel. Error: 1.36 %\n", + " Abs. Error: 0.03 g / 0.32 m/s^2\n", + "\n", + "Centrifugal acceleration at 4.58 Hz:\n", + " Theory: 4.64 g / 45.55 m/s^2\n", + " Measurement: 4.61 g / 45.215765910987294 m/s^2\n", + " Rel. Error: 0.73 %\n", + " Abs. Error: 0.03 g / 0.33 m/s^2\n", + "\n", + "Centrifugal acceleration at 5.03 Hz:\n", + " Theory: 5.60 g / 54.94 m/s^2\n", + " Measurement: 5.60 g / 54.879353326521255 m/s^2\n", + " Rel. Error: 0.10 %\n", + " Abs. Error: 0.01 g / 0.06 m/s^2\n", + "\n", + "Centrifugal acceleration at 5.64 Hz:\n", + " Theory: 7.04 g / 69.07 m/s^2\n", + " Measurement: 7.07 g / 69.32805905894263 m/s^2\n", + " Rel. Error: -0.37 %\n", + " Abs. Error: -0.03 g / -0.26 m/s^2\n", + "\n", + "Centrifugal acceleration at 6.27 Hz:\n", + " Theory: 8.70 g / 85.36 m/s^2\n", + " Measurement: 8.73 g / 85.58819751832274 m/s^2\n", + " Rel. Error: -0.27 %\n", + " Abs. Error: -0.02 g / -0.23 m/s^2\n", + "\n", + "Centrifugal acceleration at 6.92 Hz:\n", + " Theory: 10.60 g / 103.98 m/s^2\n", + " Measurement: 10.61 g / 104.02675841921068 m/s^2\n", + " Rel. Error: -0.05 %\n", + " Abs. Error: -0.01 g / -0.05 m/s^2\n", + "\n", + "Centrifugal acceleration at 7.52 Hz:\n", + " Theory: 12.52 g / 122.79 m/s^2\n", + " Measurement: 12.55 g / 123.06283558349547 m/s^2\n", + " Rel. Error: -0.22 %\n", + " Abs. Error: -0.03 g / -0.27 m/s^2\n", + "\n", + "Centrifugal acceleration at 8.11 Hz:\n", + " Theory: 14.56 g / 142.81 m/s^2\n", + " Measurement: 14.60 g / 143.1378855707173 m/s^2\n", + " Rel. Error: -0.23 %\n", + " Abs. Error: -0.03 g / -0.33 m/s^2\n", + "\n", + "Centrifugal acceleration at 8.83 Hz:\n", + " Theory: 17.26 g / 169.29 m/s^2\n", + " Measurement: 17.29 g / 169.5411921794013 m/s^2\n", + " Rel. Error: -0.15 %\n", + " Abs. Error: -0.03 g / -0.25 m/s^2\n", + "\n", + "Centrifugal acceleration at 9.34 Hz:\n", + " Theory: 19.32 g / 189.42 m/s^2\n", + " Measurement: 19.33 g / 189.55282064313795 m/s^2\n", + " Rel. Error: -0.07 %\n", + " Abs. Error: -0.01 g / -0.14 m/s^2\n", + "\n", + "Centrifugal acceleration at 10.08 Hz:\n", + " Theory: 22.50 g / 220.62 m/s^2\n", + " Measurement: 22.64 g / 222.01323904535036 m/s^2\n", + " Rel. Error: -0.63 %\n", + " Abs. Error: -0.14 g / -1.39 m/s^2\n", + "\n", + "Centrifugal acceleration at 10.92 Hz:\n", + " Theory: 26.40 g / 258.92 m/s^2\n", + " Measurement: 26.44 g / 259.29404953313013 m/s^2\n", + " Rel. Error: -0.14 %\n", + " Abs. Error: -0.04 g / -0.37 m/s^2\n", + "\n", + "Centrifugal acceleration at 11.92 Hz:\n", + " Theory: 31.46 g / 308.51 m/s^2\n", + " Measurement: 31.43 g / 308.2330187199834 m/s^2\n", + " Rel. Error: 0.09 %\n", + " Abs. Error: 0.03 g / 0.28 m/s^2\n", + "\n", + "Centrifugal acceleration at 13.24 Hz:\n", + " Theory: 38.81 g / 380.63 m/s^2\n", + " Measurement: 38.83 g / 380.7555308252864 m/s^2\n", + " Rel. Error: -0.03 %\n", + " Abs. Error: -0.01 g / -0.13 m/s^2\n", + "\n", + "Centrifugal acceleration at 14.10 Hz:\n", + " Theory: 44.02 g / 431.68 m/s^2\n", + " Measurement: 44.00 g / 431.4606825509938 m/s^2\n", + " Rel. Error: 0.05 %\n", + " Abs. Error: 0.02 g / 0.22 m/s^2\n", + "\n", + "Centrifugal acceleration at 15.18 Hz:\n", + " Theory: 51.02 g / 500.34 m/s^2\n", + " Measurement: 50.93 g / 499.4553254402874 m/s^2\n", + " Rel. Error: 0.18 %\n", + " Abs. Error: 0.09 g / 0.89 m/s^2\n", + "\n", + "Centrifugal acceleration at 16.39 Hz:\n", + " Theory: 59.48 g / 583.28 m/s^2\n", + " Measurement: 59.48 g / 583.3128315154445 m/s^2\n", + " Rel. Error: -0.00 %\n", + " Abs. Error: -0.00 g / -0.03 m/s^2\n", + "\n" + ] + } + ], + "source": [ + "t, y, _1, _2 = load_run(50, plot=False)\n", + "\n", + "ivl_start, ivl_end = 0.5, 1\n", + "ivl_start, ivl_end = int(ivl_start*60*sampling_rate), int(ivl_end*60*sampling_rate)\n", + "\n", + "fig, ax = plt.subplots(figsize=(8, 5))\n", + "#ax.axvspan(ivl_start/60/sampling_rate, ivl_end/60/sampling_rate, color='orange', alpha=0.5)\n", + "\n", + "# Run 40\n", + "#le_data = [(0, 50, 3.12), (1,50,5.55), (2,40, 8.2), (3, 30, 10.2), (4,15, 12.5), (5,10, 15.6),\n", + "# (6,10, 19.2), (7,11, 11.6), (8,15, 6.49)]\n", + "# avg_include = [True, True, True, True, True, False, True, True, True]\n", + "\n", + "# Run 50\n", + "le_data = [\n", + " 1.58, 2.11, 2.85, 3.30, 4.58, 5.03, 5.64, 6.27, 6.92, 7.52, 8.11, 8.83, 9.34, 10.08, 10.92, 11.92,\n", + " 13.24, 14.10, 15.18, 16.39\n", + "]\n", + "le_data = [ (i*90 + 45, i*90 + 45 + 40, f) for i, f in enumerate(le_data) ]\n", + "\n", + "# Run 52\n", + "#le_data = [ 3.21, 4.10, 5.09, 6.18, 7.04, 8.13, 9.41, 10.37, 11.44, 12.64, 14.06, 15.10, 16.07, 17.33 ]\n", + "#le_data = [ (i*90 + 45, i*90 + 45 + 30, f) for i, f in enumerate(le_data) ]\n", + "\n", + "avg_include = [True] * len(le_data)\n", + "\n", + "acc_theory = []\n", + "acc_meas = []\n", + "\n", + "#for ts_m, ts_s, f_actual in le_data:\n", + "for ts_start, ts_end, f_actual in le_data:\n", + " omegan = 2*np.pi*f_actual # angular velocity\n", + " acc = omegan**2 * r_mems # m/s^2\n", + " acc_theory.append(acc / g)\n", + " \n", + " #ax.axvspan(ts_abs-ivl_w/2, ts_abs+ivl_w/2, zorder=1, color='red', alpha=0.1)\n", + " \n", + " idx = (ts_start/60 < t) & (t < ts_end/60)\n", + " ivl_avg = (y / mems_lsb_per_g)[idx].mean()\n", + " acc_meas.append(ivl_avg)\n", + " \n", + "for (_1, prev_end, _2), (next_start, _3, _4) in zip([(None, 0, None)] + le_data, le_data + [(len(le_data)*90+45, None, None)]):\n", + " ax.axvspan(prev_end/60, next_start/60, zorder=1, color='black', alpha=0.05)\n", + "\n", + "# Calculate offset correction. The offset is due to manufacturing imperfections inherent to the device.\n", + "# Note that while in the \"0Hz\" still part of the line at the beginning and end of the trace we see a\n", + "# fraction of earth's gravity due to the sensor's position inside the device and the way the device lies\n", + "# on the workbench, this offset cancels out once the device is rotating.\n", + "#\n", + "# Our sensor is specified to have up to +/- 1.0 g offset. This is due to its large +/- 120 g range\n", + "# and we're well within that.\n", + "#\n", + "# The sensor's nonlinearity error is specified as +/- 2 %FS and we're well within that as well.\n", + "\n", + "def fun(x, *args):\n", + " return np.sqrt(np.mean([ ((meas - x[0])*x[1] - theory)**2\n", + " for theory, meas, inc in zip(acc_theory, acc_meas, avg_include)\n", + " if inc ]))\n", + "res = scipy.optimize.minimize(fun, (1, 1))\n", + "sensor_offx = res.x[0]\n", + "sensor_scale = np.abs(res.x[1])\n", + "\n", + "print(f'Found sensor offset: {sensor_offx:.2f} g / {sensor_offx*g:.2f} m/s^2')\n", + "print(f'Found sensor scale: {sensor_scale-1.0:+.3f}')\n", + "print() \n", + "\n", + "plot_measurements(ax, t, y, offset=sensor_offx, scale=sensor_scale, grid=False, label='Accelerometer readings')\n", + "\n", + "ax.axhline(0, linewidth=1, color='black', alpha=0.5, zorder=1)\n", + "\n", + "label = {'label': 'Theoretical results from direct frequency measurement'}\n", + "for theory, meas, (_1, _2, f_actual) in zip(acc_theory, acc_meas, le_data):\n", + " ax.axhline(theory, color='orange', alpha=1, zorder=1, linewidth=1, **label)\n", + " label = {}\n", + " meas = (meas - sensor_offx) * sensor_scale\n", + " #ax.axhline(meas, color='red', alpha=0.2, zorder=1)\n", + " \n", + " print(f'Centrifugal acceleration at {f_actual:.2f} Hz:')\n", + " print(f' Theory: {theory:.2f} g / {theory*g:.2f} m/s^2')\n", + " print(f' Measurement: {meas:.2f} g / {meas*g} m/s^2')\n", + " print(f' Rel. Error: {(theory/meas - 1.0) * 100:.2f} %')\n", + " print(f' Abs. Error: {theory-meas:.2f} g / {(theory-meas)*g:.2f} m/s^2')\n", + " print()\n", + "\n", + "ax.legend(loc='upper left')\n", + "fig.tight_layout()\n", + "fig.savefig('fig-acc-trace-steps-run50.pdf')" ] }, { "cell_type": "code", "execution_count": 84, - "metadata": { - "scrolled": false - }, + "metadata": {}, "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Loading run #40 with 4762 packets total, 682 distinct over 572.8108429908752s\n", - "Packet length: 40\n", - "Very approximate lower bound on baudrate: 129032.25806451612 bd\n", - "Sequence number range: 739 ... 1457\n" - ] - }, { "data": { "application/javascript": [ @@ -2107,7 +3305,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -2117,140 +3315,64 @@ "output_type": "display_data" }, { - "name": "stdout", - "output_type": "stream", - "text": [ - "Found sensor offset: 0.57 g / 5.55 m/s^2\n", - "\n", - "Centrifugal acceleration at 3.12 Hz:\n", - " Theory: 2.16 g / 21.14 m/s^2\n", - " Measurement: 1.90 g / 18.586194313627637 m/s^2\n", - " Rel. Error: 13.72 %\n", - " Abs. Error: 0.26 g / 2.55 m/s^2\n", - "\n", - "Centrifugal acceleration at 5.55 Hz:\n", - " Theory: 6.82 g / 66.88 m/s^2\n", - " Measurement: 6.60 g / 64.67817413725541 m/s^2\n", - " Rel. Error: 3.41 %\n", - " Abs. Error: 0.22 g / 2.20 m/s^2\n", - "\n", - "Centrifugal acceleration at 8.20 Hz:\n", - " Theory: 14.89 g / 146.00 m/s^2\n", - " Measurement: 14.82 g / 145.35641444809548 m/s^2\n", - " Rel. Error: 0.44 %\n", - " Abs. Error: 0.07 g / 0.64 m/s^2\n", - "\n", - "Centrifugal acceleration at 10.20 Hz:\n", - " Theory: 23.04 g / 225.90 m/s^2\n", - " Measurement: 23.11 g / 226.6766272456559 m/s^2\n", - " Rel. Error: -0.34 %\n", - " Abs. Error: -0.08 g / -0.77 m/s^2\n", - "\n", - "Centrifugal acceleration at 12.50 Hz:\n", - " Theory: 34.60 g / 339.27 m/s^2\n", - " Measurement: 34.80 g / 341.26606334638393 m/s^2\n", - " Rel. Error: -0.59 %\n", - " Abs. Error: -0.20 g / -2.00 m/s^2\n", - "\n", - "Centrifugal acceleration at 15.60 Hz:\n", - " Theory: 53.88 g / 528.41 m/s^2\n", - " Measurement: 51.75 g / 507.51233891199473 m/s^2\n", - " Rel. Error: 4.12 %\n", - " Abs. Error: 2.13 g / 20.90 m/s^2\n", - "\n", - "Centrifugal acceleration at 19.20 Hz:\n", - " Theory: 81.62 g / 800.43 m/s^2\n", - " Measurement: 82.09 g / 805.0345119987545 m/s^2\n", - " Rel. Error: -0.57 %\n", - " Abs. Error: -0.47 g / -4.60 m/s^2\n", - "\n", - "Centrifugal acceleration at 11.60 Hz:\n", - " Theory: 29.79 g / 292.17 m/s^2\n", - " Measurement: 29.71 g / 291.36536349393447 m/s^2\n", - " Rel. Error: 0.28 %\n", - " Abs. Error: 0.08 g / 0.81 m/s^2\n", - "\n", - "Centrifugal acceleration at 6.49 Hz:\n", - " Theory: 9.33 g / 91.46 m/s^2\n", - " Measurement: 9.21 g / 90.28568973827844 m/s^2\n", - " Rel. Error: 1.30 %\n", - " Abs. Error: 0.12 g / 1.17 m/s^2\n", - "\n" - ] + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 84, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "t, y, _1, _2 = load_run(40, plot=False)\n", + "fig, ax = plt.subplots()\n", "\n", - "ivl_start, ivl_end = 0.5, 1\n", - "ivl_start, ivl_end = int(ivl_start*60*sampling_rate), int(ivl_end*60*sampling_rate)\n", + "freqs = np.array([ f_actual for (_1, _2, f_actual) in le_data ])\n", "\n", - "fig, ax = plt.subplots(figsize=(5, 3))\n", - "#ax.axvspan(ivl_start/60/sampling_rate, ivl_end/60/sampling_rate, color='orange', alpha=0.5)\n", - " \n", - "plot_measurements(ax, t, y)\n", + "acc_theory_sorted = [ acc for _f, acc in sorted(zip(freqs, acc_theory)) ]\n", + "acc_meas_sorted = [ acc for _f, acc in sorted(zip(freqs, acc_meas)) ]\n", + "freqs = sorted(freqs)\n", "\n", - "le_data = [(0, 50, 3.12), (1,50,5.55), (2,40, 8.2), (3, 30, 10.2), (4,15, 12.5), (5,10, 15.6),\n", - " (6,10, 19.2), (7,11, 11.6), (8,15, 6.49)]\n", - "avg_include = [True, True, True, True, True, False, True, True, True]\n", - "acc_theory = []\n", - "acc_meas = []\n", + "acc_meas_sorted = (np.array(acc_meas_sorted) - sensor_offx) * sensor_scale\n", "\n", - "for ts_m, ts_s, f_actual in le_data:\n", - " omegan = 2*np.pi*f_actual # angular velocity\n", - " acc = omegan**2 * r_mems # m/s^2\n", - " acc_theory.append(acc / g)\n", - " \n", - " \n", - " ts_abs = ts_m + ts_s/60\n", - " ivl_w = 0.5\n", - " \n", - " #ax.axvspan(ts_abs-ivl_w/2, ts_abs+ivl_w/2, zorder=1, color='red', alpha=0.1)\n", + "ax.plot(freqs, acc_theory_sorted, label='Theory')\n", + "ax.plot(freqs, acc_meas_sorted, '+', label='Measurements')\n", " \n", - " idx = (ts_abs - ivl_w/2 < t) & (t < ts_abs + ivl_w/2)\n", - " ivl_avg = (y / mems_lsb_per_g)[idx].mean()\n", - " acc_meas.append(ivl_avg)\n", - "\n", - "# Calculate offset correction. The offset is due to manufacturing imperfections inherent to the device.\n", - "# Note that while in the \"0Hz\" still part of the line at the beginning and end of the trace we see a\n", - "# fraction of earth's gravity due to the sensor's position inside the device and the way the device lies\n", - "# on the workbench, this offset cancels out once the device is rotating.\n", - "#\n", - "# Our sensor is specified to have up to +/- 1.0 g offset. This is due to its large +/- 120 g range\n", - "# and we're well within that.\n", - "#\n", - "# The sensor's nonlinearity error is specified as +/- 2 %FS and we're well within that as well.\n", - "\n", - "def fun(x, *args):\n", - " return np.sqrt(np.mean([ (meas - x[0] - theory)**2\n", - " for theory, meas, inc in zip(acc_theory, acc_meas, avg_include)\n", - " if inc ]))\n", - "res = scipy.optimize.minimize(fun, 1)\n", - "sensor_offx = np.abs(res.x[0])\n", - "\n", - "print(f'Found sensor offset: {sensor_offx:.2f} g / {sensor_offx*g:.2f} m/s^2')\n", - "print()\n", + "ax.grid()\n", + "ax.set_xlabel('$f\\;[Hz]$')\n", + "ax2 = ax.twiny()\n", + "x1, x2 = ax.get_xlim()\n", + "ax2.set_xlim((x1*60, x2*60))\n", + "ax2.set_xlabel('$f\\;[rpm]$')\n", + "ax.set_ylabel('$a\\;[g]$')\n", + "ax3 = ax.twinx()\n", + "y1, y2 = ax.get_ylim()\n", + "ax3.set_ylim(y1*g, y2*g)\n", + "ax3.set_ylabel('$a\\;[ms^-1]$')\n", "\n", - "for theory, meas, (_1, _2, f_actual) in zip(acc_theory, acc_meas, le_data):\n", - " ax.axhline(theory - sensor_offx, color='orange', alpha=1, zorder=1)\n", - " meas += sensor_offx\n", - " \n", - " print(f'Centrifugal acceleration at {f_actual:.2f} Hz:')\n", - " print(f' Theory: {theory:.2f} g / {theory*g:.2f} m/s^2')\n", - " print(f' Measurement: {meas:.2f} g / {meas*g} m/s^2')\n", - " print(f' Rel. Error: {(theory/meas - 1.0) * 100:.2f} %')\n", - " print(f' Abs. Error: {theory-meas:.2f} g / {(theory-meas)*g:.2f} m/s^2')\n", - " print()\n", + "ax.legend()\n", "\n", - "fig.tight_layout()\n", - "fig.savefig('fig-acc-trace-steps.pdf')" + "ax.savefig('fig-acc-theory-meas-run50.pdf')" ] }, { "cell_type": "code", - "execution_count": 22, - "metadata": {}, + "execution_count": 125, + "metadata": { + "scrolled": false + }, "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Loading run #50 with 79193 packets total, 2623 distinct over 2102.6222710609436s\n", + "Packet length: 40\n", + "Very approximate lower bound on baudrate: 129032.25806451612 bd\n", + "Sequence number range: 2121 ... 4755\n" + ] + }, { "data": { "application/javascript": [ @@ -3212,7 +4334,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -3222,46 +4344,235 @@ "output_type": "display_data" }, { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "Found sensor offset: -3.59 g / -35.21 m/s^2\n", + "Found sensor scale: -0.014\n", + "\n", + "Centrifugal acceleration at 1.58 Hz:\n", + " Theory: 0.55 g / 5.42 m/s^2\n", + " Measurement: 0.51 g / 5.028966965088801 m/s^2\n", + " Rel. Error: 7.78 %\n", + " Abs. Error: 0.04 g / 0.39 m/s^2\n", + "\n", + "Centrifugal acceleration at 2.11 Hz:\n", + " Theory: 0.99 g / 9.67 m/s^2\n", + " Measurement: 0.93 g / 9.162411313131324 m/s^2\n", + " Rel. Error: 5.51 %\n", + " Abs. Error: 0.05 g / 0.50 m/s^2\n", + "\n", + "Centrifugal acceleration at 2.85 Hz:\n", + " Theory: 1.80 g / 17.64 m/s^2\n", + " Measurement: 1.75 g / 17.17632651666313 m/s^2\n", + " Rel. Error: 2.68 %\n", + " Abs. Error: 0.05 g / 0.46 m/s^2\n", + "\n", + "Centrifugal acceleration at 3.30 Hz:\n", + " Theory: 2.41 g / 23.65 m/s^2\n", + " Measurement: 2.38 g / 23.327857994031824 m/s^2\n", + " Rel. Error: 1.36 %\n", + " Abs. Error: 0.03 g / 0.32 m/s^2\n", + "\n", + "Centrifugal acceleration at 4.58 Hz:\n", + " Theory: 4.64 g / 45.55 m/s^2\n", + " Measurement: 4.61 g / 45.215765910987294 m/s^2\n", + " Rel. Error: 0.73 %\n", + " Abs. Error: 0.03 g / 0.33 m/s^2\n", + "\n", + "Centrifugal acceleration at 5.03 Hz:\n", + " Theory: 5.60 g / 54.94 m/s^2\n", + " Measurement: 5.60 g / 54.879353326521255 m/s^2\n", + " Rel. Error: 0.10 %\n", + " Abs. Error: 0.01 g / 0.06 m/s^2\n", + "\n", + "Centrifugal acceleration at 5.64 Hz:\n", + " Theory: 7.04 g / 69.07 m/s^2\n", + " Measurement: 7.07 g / 69.32805905894263 m/s^2\n", + " Rel. Error: -0.37 %\n", + " Abs. Error: -0.03 g / -0.26 m/s^2\n", + "\n", + "Centrifugal acceleration at 6.27 Hz:\n", + " Theory: 8.70 g / 85.36 m/s^2\n", + " Measurement: 8.73 g / 85.58819751832274 m/s^2\n", + " Rel. Error: -0.27 %\n", + " Abs. Error: -0.02 g / -0.23 m/s^2\n", + "\n", + "Centrifugal acceleration at 6.92 Hz:\n", + " Theory: 10.60 g / 103.98 m/s^2\n", + " Measurement: 10.61 g / 104.02675841921068 m/s^2\n", + " Rel. Error: -0.05 %\n", + " Abs. Error: -0.01 g / -0.05 m/s^2\n", + "\n", + "Centrifugal acceleration at 7.52 Hz:\n", + " Theory: 12.52 g / 122.79 m/s^2\n", + " Measurement: 12.55 g / 123.06283558349547 m/s^2\n", + " Rel. Error: -0.22 %\n", + " Abs. Error: -0.03 g / -0.27 m/s^2\n", + "\n", + "Centrifugal acceleration at 8.11 Hz:\n", + " Theory: 14.56 g / 142.81 m/s^2\n", + " Measurement: 14.60 g / 143.1378855707173 m/s^2\n", + " Rel. Error: -0.23 %\n", + " Abs. Error: -0.03 g / -0.33 m/s^2\n", + "\n", + "Centrifugal acceleration at 8.83 Hz:\n", + " Theory: 17.26 g / 169.29 m/s^2\n", + " Measurement: 17.29 g / 169.5411921794013 m/s^2\n", + " Rel. Error: -0.15 %\n", + " Abs. Error: -0.03 g / -0.25 m/s^2\n", + "\n", + "Centrifugal acceleration at 9.34 Hz:\n", + " Theory: 19.32 g / 189.42 m/s^2\n", + " Measurement: 19.33 g / 189.55282064313795 m/s^2\n", + " Rel. Error: -0.07 %\n", + " Abs. Error: -0.01 g / -0.14 m/s^2\n", + "\n", + "Centrifugal acceleration at 10.08 Hz:\n", + " Theory: 22.50 g / 220.62 m/s^2\n", + " Measurement: 22.64 g / 222.01323904535036 m/s^2\n", + " Rel. Error: -0.63 %\n", + " Abs. Error: -0.14 g / -1.39 m/s^2\n", + "\n", + "Centrifugal acceleration at 10.92 Hz:\n", + " Theory: 26.40 g / 258.92 m/s^2\n", + " Measurement: 26.44 g / 259.29404953313013 m/s^2\n", + " Rel. Error: -0.14 %\n", + " Abs. Error: -0.04 g / -0.37 m/s^2\n", + "\n", + "Centrifugal acceleration at 11.92 Hz:\n", + " Theory: 31.46 g / 308.51 m/s^2\n", + " Measurement: 31.43 g / 308.2330187199834 m/s^2\n", + " Rel. Error: 0.09 %\n", + " Abs. Error: 0.03 g / 0.28 m/s^2\n", + "\n", + "Centrifugal acceleration at 13.24 Hz:\n", + " Theory: 38.81 g / 380.63 m/s^2\n", + " Measurement: 38.83 g / 380.7555308252864 m/s^2\n", + " Rel. Error: -0.03 %\n", + " Abs. Error: -0.01 g / -0.13 m/s^2\n", + "\n", + "Centrifugal acceleration at 14.10 Hz:\n", + " Theory: 44.02 g / 431.68 m/s^2\n", + " Measurement: 44.00 g / 431.4606825509938 m/s^2\n", + " Rel. Error: 0.05 %\n", + " Abs. Error: 0.02 g / 0.22 m/s^2\n", + "\n", + "Centrifugal acceleration at 15.18 Hz:\n", + " Theory: 51.02 g / 500.34 m/s^2\n", + " Measurement: 50.93 g / 499.4553254402874 m/s^2\n", + " Rel. Error: 0.18 %\n", + " Abs. Error: 0.09 g / 0.89 m/s^2\n", + "\n", + "Centrifugal acceleration at 16.39 Hz:\n", + " Theory: 59.48 g / 583.28 m/s^2\n", + " Measurement: 59.48 g / 583.3128315154445 m/s^2\n", + " Rel. Error: -0.00 %\n", + " Abs. Error: -0.00 g / -0.03 m/s^2\n", + "\n" + ] } ], "source": [ - "fig, ax = plt.subplots()\n", + "t, y, _1, _2 = load_run(50, plot=False)\n", "\n", - "freqs = np.array([ f_actual for (_1, _2, f_actual) in le_data ])\n", + "fig, ax = plt.subplots(figsize=(8, 5))\n", "\n", - "acc_theory_sorted = [ acc for _f, acc in sorted(zip(freqs, acc_theory)) ]\n", - "acc_meas_sorted = [ acc for _f, acc in sorted(zip(freqs, acc_meas)) ]\n", - "freqs = sorted(freqs)\n", + "# Run 50\n", + "le_data = [\n", + " 1.58, 2.11, 2.85, 3.30, 4.58, 5.03, 5.64, 6.27, 6.92, 7.52, 8.11, 8.83, 9.34, 10.08, 10.92, 11.92,\n", + " 13.24, 14.10, 15.18, 16.39\n", + "]\n", + "le_data = [ (i*90 + 45, i*90 + 45 + 40, f) for i, f in enumerate(le_data) ]\n", "\n", - "ax.plot(freqs, acc_theory_sorted, label='Theory')\n", - "ax.plot(freqs, acc_meas_sorted, label='Measurements')\n", + "avg_include = [True] * len(le_data)\n", + "\n", + "acc_theory = []\n", + "acc_meas = []\n", + "\n", + "#for ts_m, ts_s, f_actual in le_data:\n", + "for ts_start, ts_end, f_actual in le_data:\n", + " omegan = 2*np.pi*f_actual # angular velocity\n", + " acc = omegan**2 * r_mems # m/s^2\n", + " acc_theory.append(acc / g)\n", " \n", - "ax.grid()\n", - "ax.set_xlabel('$f\\;[Hz]$')\n", - "ax2 = ax.twiny()\n", - "x1, x2 = ax.get_xlim()\n", - "ax2.set_xlim((x1*60, x2*60))\n", - "ax2.set_xlabel('$f\\;[rpm]$')\n", - "ax.set_ylabel('$a\\;[g]$')\n", - "ax3 = ax.twinx()\n", - "y1, y2 = ax.get_ylim()\n", - "ax3.set_ylim(y1*g, y2*g)\n", - "ax3.set_ylabel('$a\\;[ms^-1]$')\n", + " #ax.axvspan(ts_abs-ivl_w/2, ts_abs+ivl_w/2, zorder=1, color='red', alpha=0.1)\n", + " \n", + " idx = (ts_start/60 < t) & (t < ts_end/60)\n", + " ivl_avg = (y / mems_lsb_per_g)[idx].mean()\n", + " acc_meas.append(ivl_avg)\n", + "\n", + "# Calculate offset correction. The offset is due to manufacturing imperfections inherent to the device.\n", + "# Note that while in the \"0Hz\" still part of the line at the beginning and end of the trace we see a\n", + "# fraction of earth's gravity due to the sensor's position inside the device and the way the device lies\n", + "# on the workbench, this offset cancels out once the device is rotating.\n", + "#\n", + "# Our sensor is specified to have up to +/- 1.0 g offset. This is due to its large +/- 120 g range\n", + "# and we're well within that.\n", + "#\n", + "# The sensor's nonlinearity error is specified as +/- 2 %FS and we're well within that as well.\n", + "\n", + "def fun(x, *args):\n", + " return np.sqrt(np.mean([ ((meas - x[0])*x[1] - theory)**2\n", + " for theory, meas, inc in zip(acc_theory, acc_meas, avg_include)\n", + " if inc ]))\n", + "res = scipy.optimize.minimize(fun, (1, 1))\n", + "sensor_offx = res.x[0]\n", + "sensor_scale = np.abs(res.x[1])\n", + "\n", + "print(f'Found sensor offset: {sensor_offx:.2f} g / {sensor_offx*g:.2f} m/s^2')\n", + "print(f'Found sensor scale: {sensor_scale-1.0:+.3f}')\n", + "print() \n", + "\n", + "ax.set_xlabel(r't [mm:ss]')\n", + "ax.set_ylabel(r'$a\\; [g]$')\n", + "secax_y = ax.secondary_yaxis(\n", + " 'right', functions=(g_to_ms, ms_to_g))\n", + "secax_y.set_ylabel(r'$a\\; [ms^{-1}]$')\n", + "\n", + "formatter = ticker.FuncFormatter(lambda tick, _pos: f'{int(tick):02d}:{tick*60%60:02.0f}')\n", + "ax.xaxis.set_major_formatter(formatter)\n", + "\n", + "yp = (y / mems_lsb_per_g - sensor_offx) * sensor_scale\n", + "\n", + "sos = scipy.signal.butter(8, 0.5, 'lp', fs=10, output='sos')\n", + "filtered = scipy.signal.sosfiltfilt(sos, yp)\n", + "\n", + "label = 'Raw acceleration', f'After Low Pass'\n", + "for t_start, t_end, _f in le_data:\n", + " idx = (t_start/60 < t) & (t < t_end/60)\n", + " new_t = t[idx]\n", + " new_t -= min(new_t)\n", + " ax.plot(new_t, yp[idx], color='darkblue', alpha=0.2, label=label[0])\n", + " ax.plot(new_t, filtered[idx], color='darkblue', label=label[1])\n", + " label = (None, None)\n", "\n", - "ax.legend()" + "ax.axhline(0, linewidth=1, color='black', alpha=0.5, zorder=1)\n", + "\n", + "label = {'label': 'Calculated from rotor speed'}\n", + "for theory, meas, (_1, _2, f_actual) in zip(acc_theory, acc_meas, le_data):\n", + " ax.axhline(theory, color='orange', alpha=1, zorder=1, linewidth=1, **label)\n", + " label = {}\n", + " meas = (meas - sensor_offx) * sensor_scale\n", + " #ax.axhline(meas, color='red', alpha=0.2, zorder=1)\n", + " \n", + " print(f'Centrifugal acceleration at {f_actual:.2f} Hz:')\n", + " print(f' Theory: {theory:.2f} g / {theory*g:.2f} m/s^2')\n", + " print(f' Measurement: {meas:.2f} g / {meas*g} m/s^2')\n", + " print(f' Rel. Error: {(theory/meas - 1.0) * 100:.2f} %')\n", + " print(f' Abs. Error: {theory-meas:.2f} g / {(theory-meas)*g:.2f} m/s^2')\n", + " print()\n", + "\n", + "ax.legend(loc='upper left')\n", + "#ax.set_yscale('log')\n", + "#ax.set_ylim([0.3, 30])\n", + "fig.tight_layout()\n", + "fig.savefig('fig-acc-trace-stacked-run50.pdf')" ] }, { "cell_type": "code", - "execution_count": 77, + "execution_count": 8, "metadata": { "scrolled": false }, @@ -4362,7 +5673,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 9, "metadata": { "scrolled": false }, @@ -5366,7 +6677,7 @@ "4.3273542600896855" ] }, - "execution_count": 12, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -5412,7 +6723,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 10, "metadata": { "scrolled": false }, @@ -6385,7 +7696,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -6410,7 +7721,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -7386,10 +8697,10 @@ { "data": { "text/plain": [ - "[]" + "[]" ] }, - "execution_count": 14, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -7403,7 +8714,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 12, "metadata": { "scrolled": false }, @@ -8604,7 +9915,7 @@ }, { "cell_type": "code", - "execution_count": 89, + "execution_count": 13, "metadata": {}, "outputs": [ { @@ -10616,7 +11927,7 @@ "\n", "#ax = ax.twinx()\n", "ax.grid()\n", - "ax.plot(freqs, [ delta_rel*100 for _delta_abs, delta_rel in deltas[:-1] ])#, color='orange')\n", + "ax.plot(freqs, [ delta_rel*100 for _delta_abs, delta_rel in deltas[:-2] ])#, color='orange')\n", "ax.set_ylabel('$\\Delta_{rel}\\;[\\%]$')\n", "\n", "ax.set_xlabel('$f\\;[Hz]$')" @@ -11590,7 +12901,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -11608,42 +12919,73 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 26, "metadata": {}, "outputs": [ { - "ename": "NameError", - "evalue": "name 'largest_peak_f' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mr_mems\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m55e-3\u001b[0m \u001b[0;31m# radius of our sensor from the axis of rotation in m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mf\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlargest_peak_f\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0momega\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpi\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mf\u001b[0m \u001b[0;31m# angular velocity\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mcentrifugal_acceleration\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0momega\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0;36m2\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0mr_mems\u001b[0m \u001b[0;31m# m/s^2\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mNameError\u001b[0m: name 'largest_peak_f' is not defined" + "name": "stdout", + "output_type": "stream", + "text": [ + "Centrifugal acceleration at 7.50 Hz: 122.14 m/s^2 / 12.45 g\n", + "Centrifugal acceleration at 15.00 Hz: 488.55 m/s^2 / 49.82 g\n" ] } ], "source": [ "r_mems = 55e-3 # radius of our sensor from the axis of rotation in m\n", - "f = largest_peak_f\n", + "f = 7.5\n", "omega = 2*np.pi*f # angular velocity\n", "centrifugal_acceleration = omega**2 * r_mems # m/s^2\n", "\n", - "f2 = 1/interval\n", + "f2 = 15\n", "omega2 = 2*np.pi*f2 # angular velocity\n", "centrifugal_acceleration2 = omega2**2 * r_mems # m/s^2\n", "\n", - "print(f'Centrifugal acceleration at {largest_peak_f:.2f} Hz: {centrifugal_acceleration:.2f} m/s^2 / {centrifugal_acceleration/g:.2f} g')\n", + "print(f'Centrifugal acceleration at {f:.2f} Hz: {centrifugal_acceleration:.2f} m/s^2 / {centrifugal_acceleration/g:.2f} g')\n", "print(f'Centrifugal acceleration at {f2:.2f} Hz: {centrifugal_acceleration2:.2f} m/s^2 / {centrifugal_acceleration2/g:.2f} g')" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 27, "metadata": { "scrolled": false }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Centrifugal acceleration at 0.10 Hz: 0.02 m/s^2 / 0.00 g\n", + "Centrifugal acceleration at 0.20 Hz: 0.09 m/s^2 / 0.01 g\n", + "Centrifugal acceleration at 0.50 Hz: 0.54 m/s^2 / 0.06 g\n", + "Centrifugal acceleration at 1.00 Hz: 2.17 m/s^2 / 0.22 g\n", + "Centrifugal acceleration at 1.50 Hz: 4.89 m/s^2 / 0.50 g\n", + "Centrifugal acceleration at 2.00 Hz: 8.69 m/s^2 / 0.89 g\n", + "Centrifugal acceleration at 2.50 Hz: 13.57 m/s^2 / 1.38 g\n", + "Centrifugal acceleration at 3.00 Hz: 19.54 m/s^2 / 1.99 g\n", + "Centrifugal acceleration at 3.50 Hz: 26.60 m/s^2 / 2.71 g\n", + "Centrifugal acceleration at 4.00 Hz: 34.74 m/s^2 / 3.54 g\n", + "Centrifugal acceleration at 4.50 Hz: 43.97 m/s^2 / 4.48 g\n", + "Centrifugal acceleration at 5.00 Hz: 54.28 m/s^2 / 5.54 g\n", + "Centrifugal acceleration at 6.00 Hz: 78.17 m/s^2 / 7.97 g\n", + "Centrifugal acceleration at 7.00 Hz: 106.39 m/s^2 / 10.85 g\n", + "Centrifugal acceleration at 8.00 Hz: 138.96 m/s^2 / 14.17 g\n", + "Centrifugal acceleration at 9.00 Hz: 175.88 m/s^2 / 17.93 g\n", + "Centrifugal acceleration at 10.00 Hz: 217.13 m/s^2 / 22.14 g\n", + "Centrifugal acceleration at 11.00 Hz: 262.73 m/s^2 / 26.79 g\n", + "Centrifugal acceleration at 12.00 Hz: 312.67 m/s^2 / 31.88 g\n", + "Centrifugal acceleration at 13.00 Hz: 366.95 m/s^2 / 37.42 g\n", + "Centrifugal acceleration at 14.00 Hz: 425.58 m/s^2 / 43.40 g\n", + "Centrifugal acceleration at 15.00 Hz: 488.55 m/s^2 / 49.82 g\n", + "Centrifugal acceleration at 16.00 Hz: 555.86 m/s^2 / 56.68 g\n", + "Centrifugal acceleration at 17.00 Hz: 627.51 m/s^2 / 63.99 g\n", + "Centrifugal acceleration at 18.00 Hz: 703.51 m/s^2 / 71.74 g\n", + "Centrifugal acceleration at 19.00 Hz: 783.84 m/s^2 / 79.93 g\n", + "Centrifugal acceleration at 20.00 Hz: 868.53 m/s^2 / 88.57 g\n" + ] + } + ], "source": [ "for fn in [0.1, 0.2, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0,\n", " 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0]:\n", @@ -11655,7 +12997,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 28, "metadata": {}, "outputs": [ { @@ -12619,7 +13961,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -12630,13 +13972,13 @@ }, { "ename": "NameError", - "evalue": "name 'centrifugal_acceleration' is not defined", + "evalue": "name 'interval' is not defined", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mfig\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0max\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msubplots\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0max\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0maxvspan\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mivl_start\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0;36m60\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0msampling_rate\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mivl_end\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0;36m60\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0msampling_rate\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcolor\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'orange'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0malpha\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0.5\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0max\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0maxhline\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcentrifugal_acceleration\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0mg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcolor\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'orange'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 7\u001b[0m \u001b[0max\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0maxhline\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcentrifugal_acceleration2\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0mg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcolor\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'orange'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0minterval\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mNameError\u001b[0m: name 'centrifugal_acceleration' is not defined" + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0max\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0maxhline\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcentrifugal_acceleration\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0mg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcolor\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'orange'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[0max\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0maxhline\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcentrifugal_acceleration2\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0mg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcolor\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'orange'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 8\u001b[0;31m \u001b[0minterval\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 9\u001b[0m \u001b[0mts\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mreassembled_values\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0msampling_rate\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0;36m60\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0max\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mts\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mreassembled_values\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0mmems_lsb_per_g\u001b[0m \u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mNameError\u001b[0m: name 'interval' is not defined" ] } ], diff --git a/prototype/sensor-analysis/fig-acc-theory-meas-run50.pdf b/prototype/sensor-analysis/fig-acc-theory-meas-run50.pdf new file mode 100644 index 0000000..8f86fb9 Binary files /dev/null and b/prototype/sensor-analysis/fig-acc-theory-meas-run50.pdf differ diff --git a/prototype/sensor-analysis/fig-acc-theory-meas.pdf b/prototype/sensor-analysis/fig-acc-theory-meas.pdf new file mode 100644 index 0000000..87be879 Binary files /dev/null and b/prototype/sensor-analysis/fig-acc-theory-meas.pdf differ diff --git a/prototype/sensor-analysis/fig-acc-trace-stacked-run50.pdf b/prototype/sensor-analysis/fig-acc-trace-stacked-run50.pdf new file mode 100644 index 0000000..3c3193c Binary files /dev/null and b/prototype/sensor-analysis/fig-acc-trace-stacked-run50.pdf differ diff --git a/prototype/sensor-analysis/fig-acc-trace-steps-run50.pdf b/prototype/sensor-analysis/fig-acc-trace-steps-run50.pdf new file mode 100644 index 0000000..8d5c65f Binary files /dev/null and b/prototype/sensor-analysis/fig-acc-trace-steps-run50.pdf differ diff --git a/prototype/sensor-analysis/fig-acc-trace-steps-run52.pdf b/prototype/sensor-analysis/fig-acc-trace-steps-run52.pdf new file mode 100644 index 0000000..5966cdd Binary files /dev/null and b/prototype/sensor-analysis/fig-acc-trace-steps-run52.pdf differ diff --git a/prototype/sensor-analysis/fig-comms-delays.pdf b/prototype/sensor-analysis/fig-comms-delays.pdf new file mode 100644 index 0000000..2b3a686 Binary files /dev/null and b/prototype/sensor-analysis/fig-comms-delays.pdf differ diff --git a/prototype/sensor-analysis/test_run.sqlite3 b/prototype/sensor-analysis/test_run.sqlite3 index e570594..92cbc3b 100755 Binary files a/prototype/sensor-analysis/test_run.sqlite3 and b/prototype/sensor-analysis/test_run.sqlite3 differ -- cgit