initial implementation of accel graph in motors tab
parent
9e15e55e3f
commit
d128bd76a5
|
@ -1,97 +1,183 @@
|
|||
.tab-motor_outputs {
|
||||
.tab-motor_outputs .plot_control {
|
||||
float: right;
|
||||
|
||||
width: 158px;
|
||||
|
||||
border: 1px solid silver;
|
||||
}
|
||||
.tab-motor_outputs .left.motors {
|
||||
.tab-motor_outputs .plot_control .title {
|
||||
line-height: 20px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
|
||||
border-bottom: 1px solid silver;
|
||||
background-color: #ececec;
|
||||
}
|
||||
.tab-motor_outputs .plot_control dl {
|
||||
padding: 5px 0 0 5px;
|
||||
line-height: 22px;
|
||||
}
|
||||
.tab-motor_outputs .plot_control dt {
|
||||
float: left;
|
||||
|
||||
width: 60px;
|
||||
height: 22px;
|
||||
|
||||
font-weight: bold;
|
||||
}
|
||||
.tab-motor_outputs .plot_control dd {
|
||||
margin-left: 20px;
|
||||
height: 22px;
|
||||
}
|
||||
.tab-motor_outputs .plot_control .x {
|
||||
color: #00A8F0;
|
||||
}
|
||||
.tab-motor_outputs .plot_control .y {
|
||||
color: #C0D800;
|
||||
}
|
||||
.tab-motor_outputs .plot_control .z {
|
||||
color: #CB4B4B;
|
||||
}
|
||||
.tab-motor_outputs select {
|
||||
width: 70px;
|
||||
border: 1px solid silver;
|
||||
}
|
||||
.tab-motor_outputs svg {
|
||||
float: left;
|
||||
|
||||
width: calc(100% - 168px); /* - (plot control, margin)*/
|
||||
height: 140px;
|
||||
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.tab-motor_outputs .grid .tick {
|
||||
stroke: silver;
|
||||
stroke-width: 1px;
|
||||
shape-rendering: crispEdges;
|
||||
}
|
||||
.tab-motor_outputs .grid path {
|
||||
stroke-width: 0;
|
||||
}
|
||||
.tab-motor_outputs .data .line {
|
||||
stroke-width: 2px;
|
||||
fill: none;
|
||||
}
|
||||
.tab-motor_outputs .axis path, .tab-motor_outputs .axis line {
|
||||
fill: none;
|
||||
stroke: #000000;
|
||||
stroke-width: 1px;
|
||||
shape-rendering: crispEdges;
|
||||
}
|
||||
.tab-motor_outputs .line:nth-child(1) {
|
||||
stroke: #00A8F0;
|
||||
}
|
||||
.tab-motor_outputs .line:nth-child(2) {
|
||||
stroke: #C0D800;
|
||||
}
|
||||
.tab-motor_outputs .line:nth-child(3) {
|
||||
stroke: #CB4B4B;
|
||||
}
|
||||
|
||||
.tab-motor_outputs .left.motors {
|
||||
float: left;
|
||||
|
||||
margin-right: 50px;
|
||||
|
||||
width: calc(50% - 50px);
|
||||
}
|
||||
.tab-motor_outputs .right.servos {
|
||||
float: left;
|
||||
|
||||
width: 50%;
|
||||
}
|
||||
.tab-motor_outputs .titles {
|
||||
height: 20px;
|
||||
}
|
||||
.tab-motor_outputs .titles li {
|
||||
float: left;
|
||||
|
||||
width: calc((100% / 9) - 10px);
|
||||
margin-right: 10px;
|
||||
|
||||
text-align: center;
|
||||
}
|
||||
.tab-motor_outputs .servos .titles li {
|
||||
float: right;
|
||||
|
||||
width: calc((100% / 8) - 10px);
|
||||
|
||||
margin: 0 0 0 10px;
|
||||
}
|
||||
.tab-motor_outputs .titles .active {
|
||||
color: green;
|
||||
}
|
||||
.tab-motor_outputs .m-block {
|
||||
float: left;
|
||||
|
||||
width: calc((100% / 9) - 12px);
|
||||
height: 80px;
|
||||
|
||||
margin-right: 10px;
|
||||
|
||||
border: 1px solid silver;
|
||||
background-color: #e9e9e9;
|
||||
}
|
||||
.tab-motor_outputs .servos .m-block {
|
||||
float: right;
|
||||
|
||||
width: calc((100% / 8) - 12px);
|
||||
|
||||
margin: 0 0 0 10px;
|
||||
}
|
||||
.tab-motor_outputs .indicator {
|
||||
float: left;
|
||||
|
||||
width: 100%;
|
||||
}
|
||||
.tab-motor_outputs p {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
padding: 5px;
|
||||
|
||||
border: 1px dotted silver;
|
||||
}
|
||||
.tab-motor_outputs .motor_testing {
|
||||
display: none;
|
||||
}
|
||||
.tab-motor_outputs .motor_testing .left {
|
||||
margin-right: 50px;
|
||||
|
||||
width: calc(50% - 50px);
|
||||
}
|
||||
.tab-motor_outputs .right.servos {
|
||||
float: left;
|
||||
.tab-motor_outputs .motor_testing .sliders {
|
||||
}
|
||||
.tab-motor_outputs .motor_testing .sliders input {
|
||||
-webkit-appearance: slider-vertical;
|
||||
|
||||
width: 50%;
|
||||
width: calc((100% / 9) - 3px); /* - (width / 9 elements, not sure about -3 */
|
||||
height: 80px;
|
||||
}
|
||||
.tab-motor_outputs .motor_testing .values {
|
||||
margin-top: 5px;
|
||||
}
|
||||
.tab-motor_outputs .titles {
|
||||
height: 20px;
|
||||
}
|
||||
.tab-motor_outputs .titles li {
|
||||
.tab-motor_outputs .motor_testing .values li {
|
||||
float: left;
|
||||
|
||||
width: calc((100% / 9) - 10px); /* - (margin) */
|
||||
margin-right: 10px;
|
||||
width: calc((100% / 9));
|
||||
|
||||
text-align: center;
|
||||
}
|
||||
.tab-motor_outputs .servos .titles li {
|
||||
width: calc((100% / 8) - 10px); /* - (margin) */
|
||||
}
|
||||
.tab-motor_outputs .titles .active {
|
||||
color: green;
|
||||
}
|
||||
.tab-motor_outputs .m-block {
|
||||
float: left;
|
||||
.tab-motor_outputs .motor_testing .notice {
|
||||
float: right;
|
||||
|
||||
width: calc((100% / 9) - 12px); /* - (margin, border) */
|
||||
height: 160px;
|
||||
width: calc(50% - 22px);
|
||||
|
||||
margin-right: 10px;
|
||||
|
||||
border: 1px solid silver;
|
||||
background-color: #e9e9e9;
|
||||
}
|
||||
.tab-motor_outputs .servos .m-block {
|
||||
width: calc((100% / 8) - 12px); /* - (margin, border) */
|
||||
}
|
||||
.tab-motor_outputs .indicator {
|
||||
float: left;
|
||||
|
||||
width: 100%;
|
||||
}
|
||||
.tab-motor_outputs p {
|
||||
margin-top: 20px;
|
||||
padding: 5px;
|
||||
|
||||
border: 1px dotted silver;
|
||||
}
|
||||
.tab-motor_outputs .motor_testing {
|
||||
display: none;
|
||||
}
|
||||
.tab-motor_outputs .motor_testing .left {
|
||||
margin-right: 50px;
|
||||
.tab-motor_outputs .motor_testing .notice input[type="checkbox"] {
|
||||
margin-left: 5px;
|
||||
|
||||
width: calc(50% - 50px);
|
||||
}
|
||||
.tab-motor_outputs .motor_testing .sliders {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.tab-motor_outputs .motor_testing .sliders input {
|
||||
-webkit-appearance: slider-vertical;
|
||||
|
||||
width: calc((100% / 9) - 3px); /* - (width / 9 elements, not sure about -3 */
|
||||
}
|
||||
.tab-motor_outputs .motor_testing .values {
|
||||
margin-top: 5px;
|
||||
}
|
||||
.tab-motor_outputs .motor_testing .values li {
|
||||
float: left;
|
||||
|
||||
width: calc((100% / 9));
|
||||
|
||||
text-align: center;
|
||||
}
|
||||
.tab-motor_outputs .motor_testing .notice {
|
||||
float: left;
|
||||
|
||||
width: calc(50% - 12px); /* - (padding, border) */
|
||||
|
||||
margin-top: 20px;
|
||||
padding: 5px;
|
||||
|
||||
border: 1px dotted silver;
|
||||
}
|
||||
.tab-motor_outputs .motor_testing .notice input[type="checkbox"] {
|
||||
margin-left: 5px;
|
||||
|
||||
vertical-align: middle;
|
||||
}
|
||||
vertical-align: middle;
|
||||
}
|
|
@ -1,4 +1,44 @@
|
|||
<div class="tab-motor_outputs">
|
||||
<div class="wrapper accel">
|
||||
<div class="plot_control">
|
||||
<div class="title">Accelerometer - g</div>
|
||||
<dl>
|
||||
<dt i18n="sensorsRefresh"></dt>
|
||||
<dd class="rate">
|
||||
<select name="accel_refresh_rate">
|
||||
<option value="10">10 ms</option>
|
||||
<option value="20" selected="selected">20 ms</option>
|
||||
<option value="30">30 ms</option>
|
||||
<option value="40">40 ms</option>
|
||||
<option value="50">50 ms</option>
|
||||
<option value="100">100 ms</option>
|
||||
<option value="250">250 ms</option>
|
||||
<option value="500">500 ms</option>
|
||||
<option value="1000">1000 ms</option>
|
||||
</select>
|
||||
</dd>
|
||||
<dt i18n="sensorsScale"></dt>
|
||||
<dd class="scale">
|
||||
<select name="accel_scale">
|
||||
<option value="0.5">0.5</option>
|
||||
<option value="1">1</option>
|
||||
<option value="2" selected="selected">2</option>
|
||||
</select>
|
||||
</dd>
|
||||
<dt>X:</dt><dd class="x">0</dd>
|
||||
<dt>Y:</dt><dd class="y">0</dd>
|
||||
<dt>Z:</dt><dd class="z">0</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<svg id="accel">
|
||||
<g class="grid x" transform="translate(20, 120)"></g>
|
||||
<g class="grid y" transform="translate(20, 10)"></g>
|
||||
<g class="data" transform="translate(21, 10)"></g>
|
||||
<g class="axis x" transform="translate(20, 120)"></g>
|
||||
<g class="axis y" transform="translate(20, 10)"></g>
|
||||
</svg>
|
||||
<div class="clear-both"></div>
|
||||
</div>
|
||||
<div class="left motors">
|
||||
<ul class="titles">
|
||||
<li title="Motor - 1">M - 1</li>
|
||||
|
@ -23,24 +63,24 @@
|
|||
</div>
|
||||
<div class="right servos">
|
||||
<ul class="titles">
|
||||
<li title="Servo - 1">S - 1</li>
|
||||
<li title="Servo - 2">S - 2</li>
|
||||
<li title="Servo - 3">S - 3</li>
|
||||
<li title="Servo - 4">S - 4</li>
|
||||
<li title="Servo - 5">S - 5</li>
|
||||
<li title="Servo - 6">S - 6</li>
|
||||
<li title="Servo - 7">S - 7</li>
|
||||
<li title="Servo - 8">S - 8</li>
|
||||
<li title="Servo - 7">S - 7</li>
|
||||
<li title="Servo - 6">S - 6</li>
|
||||
<li title="Servo - 5">S - 5</li>
|
||||
<li title="Servo - 4">S - 4</li>
|
||||
<li title="Servo - 3">S - 3</li>
|
||||
<li title="Servo - 2">S - 2</li>
|
||||
<li title="Servo - 1">S - 1</li>
|
||||
</ul>
|
||||
<div class="bar-wrapper">
|
||||
<div class="m-block servo-0"><div class="indicator"></div></div>
|
||||
<div class="m-block servo-1"><div class="indicator"></div></div>
|
||||
<div class="m-block servo-2"><div class="indicator"></div></div>
|
||||
<div class="m-block servo-3"><div class="indicator"></div></div>
|
||||
<div class="m-block servo-4"><div class="indicator"></div></div>
|
||||
<div class="m-block servo-5"><div class="indicator"></div></div>
|
||||
<div class="m-block servo-6"><div class="indicator"></div></div>
|
||||
<div class="m-block servo-7"><div class="indicator"></div></div>
|
||||
<div class="m-block servo-6"><div class="indicator"></div></div>
|
||||
<div class="m-block servo-5"><div class="indicator"></div></div>
|
||||
<div class="m-block servo-4"><div class="indicator"></div></div>
|
||||
<div class="m-block servo-3"><div class="indicator"></div></div>
|
||||
<div class="m-block servo-2"><div class="indicator"></div></div>
|
||||
<div class="m-block servo-1"><div class="indicator"></div></div>
|
||||
<div class="m-block servo-0"><div class="indicator"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clear-both"></div>
|
||||
|
|
|
@ -2,6 +2,124 @@ function tab_initialize_motor_outputs() {
|
|||
ga_tracker.sendAppView('Motor Outputs Page');
|
||||
GUI.active_tab = 'motor_outputs';
|
||||
|
||||
function initSensorData() {
|
||||
for (var i = 0; i < 3; i++) {
|
||||
SENSOR_DATA.accelerometer[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function initDataArray(length) {
|
||||
var data = new Array(length);
|
||||
for (var i = 0; i < length; i++) {
|
||||
data[i] = new Array();
|
||||
data[i].min = -1;
|
||||
data[i].max = 1;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
function addSampleToData(data, sampleNumber, sensorData) {
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var dataPoint = sensorData[i];
|
||||
data[i].push([sampleNumber, dataPoint]);
|
||||
if (dataPoint < data[i].min) {
|
||||
data[i].min = dataPoint;
|
||||
}
|
||||
if (dataPoint > data[i].max) {
|
||||
data[i].max = dataPoint;
|
||||
}
|
||||
}
|
||||
while (data[0].length > 300) {
|
||||
for (i = 0; i < data.length; i++) {
|
||||
data[i].shift();
|
||||
}
|
||||
}
|
||||
return sampleNumber + 1;
|
||||
}
|
||||
|
||||
var margin = {top: 20, right: 10, bottom: 10, left: 20};
|
||||
function updateGraphHelperSize(helpers) {
|
||||
helpers.width = helpers.targetElement.width() - margin.left - margin.right;
|
||||
helpers.height = helpers.targetElement.height() - margin.top - margin.bottom;
|
||||
|
||||
helpers.widthScale.range([0, helpers.width]);
|
||||
helpers.heightScale.range([helpers.height, 0]);
|
||||
|
||||
helpers.xGrid.tickSize(-helpers.height, 0, 0);
|
||||
helpers.yGrid.tickSize(-helpers.width, 0, 0);
|
||||
}
|
||||
|
||||
function initGraphHelpers(selector, sampleNumber, heightDomain) {
|
||||
var helpers = {selector: selector, targetElement: $(selector), dynamicHeightDomain: !heightDomain};
|
||||
|
||||
helpers.widthScale = d3.scale.linear()
|
||||
.clamp(true)
|
||||
.domain([(sampleNumber - 299), sampleNumber]);
|
||||
|
||||
helpers.heightScale = d3.scale.linear()
|
||||
.clamp(true)
|
||||
.domain(heightDomain || [1, -1]);
|
||||
|
||||
helpers.xGrid = d3.svg.axis();
|
||||
helpers.yGrid = d3.svg.axis();
|
||||
|
||||
updateGraphHelperSize(helpers);
|
||||
|
||||
helpers.xGrid
|
||||
.scale(helpers.widthScale)
|
||||
.orient("bottom")
|
||||
.ticks(5)
|
||||
.tickFormat("");
|
||||
|
||||
helpers.yGrid
|
||||
.scale(helpers.heightScale)
|
||||
.orient("left")
|
||||
.ticks(5)
|
||||
.tickFormat("");
|
||||
|
||||
helpers.xAxis = d3.svg.axis()
|
||||
.scale(helpers.widthScale)
|
||||
.ticks(5)
|
||||
.orient("bottom")
|
||||
.tickFormat(function(d) {return d;});
|
||||
|
||||
helpers.yAxis = d3.svg.axis()
|
||||
.scale(helpers.heightScale)
|
||||
.ticks(5)
|
||||
.orient("left")
|
||||
.tickFormat(function(d) {return d;});
|
||||
|
||||
helpers.line = d3.svg.line()
|
||||
.x(function(d) { return helpers.widthScale(d[0]); })
|
||||
.y(function(d) { return helpers.heightScale(d[1]); });
|
||||
|
||||
return helpers;
|
||||
}
|
||||
|
||||
function drawGraph(graphHelpers, data, sampleNumber) {
|
||||
svg = d3.select(graphHelpers.selector);
|
||||
|
||||
if (graphHelpers.dynamicHeightDomain) {
|
||||
var limits = [];
|
||||
$.each(data, function(idx, datum) {
|
||||
limits.push(datum.min);
|
||||
limits.push(datum.max);
|
||||
});
|
||||
graphHelpers.heightScale.domain(d3.extent(limits));
|
||||
}
|
||||
graphHelpers.widthScale.domain([(sampleNumber - 299), sampleNumber]);
|
||||
|
||||
svg.select(".x.grid").call(graphHelpers.xGrid);
|
||||
svg.select(".y.grid").call(graphHelpers.yGrid);
|
||||
svg.select(".x.axis").call(graphHelpers.xAxis);
|
||||
svg.select(".y.axis").call(graphHelpers.yAxis);
|
||||
|
||||
var group = svg.select("g.data");
|
||||
var lines = group.selectAll("path").data(data, function(d, i) { return i; });
|
||||
var newLines = lines.enter().append("path").attr("class", "line");
|
||||
lines.attr('d', graphHelpers.line);
|
||||
}
|
||||
|
||||
MSP.send_message(MSP_codes.MSP_MISC, false, false, get_motor_data);
|
||||
|
||||
function get_motor_data() {
|
||||
|
@ -16,6 +134,58 @@ function tab_initialize_motor_outputs() {
|
|||
// translate to user-selected language
|
||||
localize();
|
||||
|
||||
// Always start with default/empty sensor data array, clean slate all
|
||||
initSensorData();
|
||||
|
||||
// Setup variables
|
||||
var samples_accel_i = 0;
|
||||
var accel_data = initDataArray(3);
|
||||
var accelHelpers = initGraphHelpers('#accel', samples_accel_i, [-2, 2]);
|
||||
|
||||
var raw_data_text_ements = {
|
||||
x: [],
|
||||
y: [],
|
||||
z: [],
|
||||
};
|
||||
$('.plot_control .x, .plot_control .y, .plot_control .z').each(function() {
|
||||
var el = $(this);
|
||||
if (el.hasClass('x')) {
|
||||
raw_data_text_ements.x.push(el);
|
||||
} else if (el.hasClass('y')) {
|
||||
raw_data_text_ements.y.push(el);
|
||||
} else {
|
||||
raw_data_text_ements.z.push(el);
|
||||
}
|
||||
});
|
||||
|
||||
$('.tab-motor_outputs .rate select, .tab-motor_outputs .scale select').change(function() {
|
||||
var rate = parseInt($('.tab-motor_outputs select[name="accel_refresh_rate"]').val(), 10);
|
||||
var scale = parseFloat($('.tab-motor_outputs select[name="accel_scale"]').val());
|
||||
|
||||
accelHelpers = initGraphHelpers('#accel', samples_accel_i, [-scale, scale]);
|
||||
|
||||
// timer initialization
|
||||
GUI.interval_kill_all(['motor_pull', 'status_pull']);
|
||||
|
||||
GUI.interval_add('IMU_pull', function imu_data_pull() {
|
||||
MSP.send_message(MSP_codes.MSP_RAW_IMU, false, false, update_accel_graph);
|
||||
}, rate, true);
|
||||
|
||||
function update_accel_graph() {
|
||||
updateGraphHelperSize(accelHelpers);
|
||||
|
||||
samples_accel_i = addSampleToData(accel_data, samples_accel_i, SENSOR_DATA.accelerometer);
|
||||
drawGraph(accelHelpers, accel_data, samples_accel_i);
|
||||
raw_data_text_ements.x[0].text(SENSOR_DATA.accelerometer[0].toFixed(2));
|
||||
raw_data_text_ements.y[0].text(SENSOR_DATA.accelerometer[1].toFixed(2));
|
||||
raw_data_text_ements.z[0].text(SENSOR_DATA.accelerometer[2].toFixed(2));
|
||||
}
|
||||
});
|
||||
|
||||
// fire change event to start accel plot
|
||||
$('.tab-motor_outputs .rate select:first').change();
|
||||
|
||||
|
||||
// if CAP_DYNBALANCE is true
|
||||
if (bit_check(CONFIG.capability, 2)) {
|
||||
$('div.motor_testing').show();
|
||||
|
@ -141,7 +311,7 @@ function tab_initialize_motor_outputs() {
|
|||
GUI.interval_add('motor_pull', get_motor_data, 50, true);
|
||||
|
||||
// status data pulled via separate timer with static speed
|
||||
GUI.interval_add('status_pull', function() {
|
||||
GUI.interval_add('status_pull', function get_status_data() {
|
||||
MSP.send_message(MSP_codes.MSP_STATUS);
|
||||
}, 250, true);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue