Skip to content

Commit

Permalink
Merge pull request #42 from CCGSRobotics/add-dynamixel-parser
Browse files Browse the repository at this point in the history
Add Dynamixel creation wizard
  • Loading branch information
Finchiedev authored Aug 20, 2019
2 parents 8bfa3c0 + a479dc1 commit 258b3cb
Show file tree
Hide file tree
Showing 10 changed files with 482 additions and 23 deletions.
17 changes: 17 additions & 0 deletions App/CSS/createServo.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.container {
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
}

#url {
text-align: center;
border: 1px solid;
padding: 5px;
}

#download #upload {
text-align: center;
padding: 5px;
}
33 changes: 33 additions & 0 deletions App/JS/Resources/Servos/ax18a.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
Address, Size(Byte), Data Name, Description, Access, InitialValue
0, 2, Model Number, Model Number, R, 18
2, 1, Firmware Version, Firmware Version, R, -
3, 1, ID, DYNAMIXEL ID, RW, 1
4, 1, Baud Rate, Communication Speed, RW, 1
5, 1, Return Delay Time, Response Delay Time, RW, 250
6, 2, CW Angle Limit, Clockwise Angle Limit, RW, 0
8, 2, CCW Angle Limit, Counter-Clockwise Angle Limit, RW, 1023
11, 1, Temperature Limit, Maximum Internal Temperature Limit, RW, 75
12, 1, Min Voltage Limit, Minimum Input Voltage Limit, RW, 60
13, 1, Max Voltage Limit, Maximum Input Voltage Limit, RW, 140
14, 2, Max Torque, Maximun Torque, RW, 983
16, 1, Status Return Level, Select Types of Status Return, RW, 2
17, 1, Alarm LED, LED for Alarm, RW, 36
18, 1, Shutdown, Shutdown Error Information, RW, 36
24, 1, Torque Enable, Motor Torque On/Off, RW, 0
25, 1, LED, Status LED On/Off, RW, 0
26, 1, CW Compliance Margin, CW Compliance Margin, RW, 1
27, 1, CCW Compliance Margin, CCW Compliance Margin, RW, 1
28, 1, CW Compliance Slope, CW Compliance Slope, RW, 32
29, 1, CCW Compliance Slope, CCW Compliance Slope, RW, 32
30, 2, Goal Position, Target Position, RW, -
32, 2, Moving Speed, Moving Speed, RW, -
34, 2, Torque Limit, Torque Limit(Goal Torque), RW, ADD 14&15
36, 2, Present Position, Present Position, R, -
38, 2, Present Speed, Present Speed, R, -
40, 2, Present Load, Present Load, R, -
42, 1, Present Voltage, Present Voltage, R, -
43, 1, Present Temperature, Present Temperature, R, -
44, 1, Registered, If Instruction is registered, R, 0
46, 1, Moving, Movement Status, R, 0
47, 1, Lock, Locking EEPROM, RW, 0
48, 2, Punch, Minimum Current Threshold, RW, 32
32 changes: 32 additions & 0 deletions App/JS/Resources/Servos/xl320.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
Address, Size(Byte), Data Name, Description, Access, InitialValue, Min, Max
0, 2, Model Number, Model Number, R, 350, -, -
2, 1, Firmware Version, Firmware Version, R, -, -, -
3, 1, ID, DYNAMIXEL ID, RW, 1, 0, 252
4, 1, Baud Rate, Communication Speed, RW, 3, 0, 3
5, 1, Return Delay Time, Response Delay Time, RW, 250, 0, 254
6, 2, CW Angle Limit, Clockwise Angle Limit, RW, 0, 0, 1023
8, 2, CCW Angle Limit, Counter-Clockwise Angle Limit, RW, 1023, 0, 1023
11, 1, Control Mode, Control Mode, RW, 2, 1, 2
12, 1, Temperature Limit, Maximum Internal Temperature Limit, RW, 65, 0, 150
13, 1, Min Voltage Limit, Minimum Input Voltage Limit, RW, 60, 50, 250
14, 1, Max Voltage Limit, Maximum Input Voltage Limit, RW, 90, 50, 250
15, 2, Max Torque, Maximun Torque, RW, 1023, 0, 1023
17, 1, Status Return Level, Select Types of Status Return, RW, 2, 0, 2
18, 1, Shutdown, Shutdown Error Information, RW, 3, 0, 7
24, 1, Torque Enable, Motor Torque On/Off, RW, 0, 0, 1
25, 1, LED, Status LED On/Off, RW, 0, 0, 7
27, 1, D Gain, Derivative Gain, RW, 0, 0, 254
28, 1, I Gain, Integral Gain, RW, 0, 0, 254
29, 1, P Gain, Proportional Gain, RW, 32, 0, 254
30, 2, Goal Position, Desired Position, RW, -, 0, 1023
32, 2, Moving Speed, Moving Speed(Moving Velocity), RW, -, 0, 2047
35, 2, Torque Limit, Torque Limit(Goal Torque), RW, -, 0, 1023
37, 2, Present Position, Present Position, R, -, -, -
39, 2, Present Speed, Present Speed, R, -, -, -
41, 2, Present Load, Present Load, R, -, -, -
45, 1, Present Voltage, Present Voltage, R, -, -, -
46, 1, Present Temperature, Present Temperature, R, -, -, -
47, 1, Registered, If Instruction is registered, R, 0, -, -
49, 1, Moving, Movement Status, R, 0, -, -
50, 1, Hardware Error Status, Hardware Error Status, R, 0, -, -
51, 2, Punch, Minimum Current Threshold, RW, 32, 0, 1023
154 changes: 154 additions & 0 deletions App/JS/createServo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
const fs = require('fs');
const rp = require('request-promise');
const cheerio = require('cheerio');
const cheerioTableparser = require('cheerio-tableparser');
const net = require('net');
let link = '';
let fileData = '';
let filename = '';

const client = new net.Socket();
client.on('error', function(err) {
console.error('Unable to connect to the fileserver!' + '\n' +
' Ensure that the robot is powered and active.');
});

/**
* Parses the header of a given table
* @param {Array} table
* @return {String} The header of the specified table
*/
function parseDynamixelHeader(table) {
let build = '';
for (let col = 0; col < table.length; col++) {
build += table[col][0];
if (col < table.length - 1) {
build += ', ';
} else {
build += '\n';
}
}
return build;
}

/**
* Parses all elements in a given Dynamixel table and converts them to CSV
* @param {Object} table The table returned when executing parsetable
* @param {Boolean} includeHeader If the CSV should include headings - use
* false if this is not the top item in the table
* @return {String} A string of CSV data with the control table
*/
function parseDynamixelTable(table) {
let build = '';
for (let i = 1; i < table[0].length; i++) {
for (let x = 0; x < table.length; x++) {
build += table[x][i];
if (x < table.length - 1) {
build += ', ';
}
}
if (i < table[0].length) {
build += '\n';
}
}
return build;
}

/**
* Computes all HTML tables from indexes and converts to CSV
* @param {String} html The downloaded e-Manual document as HTML
* @param {Array} indexes The indexes of all tables involving the control table
* @return {String} The CSV-formatted table containing all of the control table
*/
function generateCSV(html, indexes) {
if (indexes == null || indexes == undefined || indexes.length == 0) {
console.error('Invalid argument!' +
'Ensure that the argument "indexes" is valid!');
return '';
}

let fileData = '';
const $ = cheerio.load(html);
cheerioTableparser($);
const cheerioTable = $('table');

fileData += parseDynamixelHeader(cheerioTable.eq(
indexes[0]).parsetable(true, true, true));
for (let i = 0; i < indexes.length; i++) {
fileData += parseDynamixelTable(cheerioTable.eq(
indexes[i]).parsetable(true, true, true));
}

return fileData;
}

/**
* Downloads and converts the link to a CSV, saving it to Resources/Servos and
* storing it in the variable fileData
*/
function getFile() {
const url = document.getElementById('url').value;
const re = /^https?:\/\/emanual\.robotis\.com\/docs\/en\/dxl\/[a-z0-9]+\/[a-z0-9]+-?[a-z0-9]+/;
const res = url.match(re);
if (res !== null && res !== undefined) {
link = res[0];
console.log(`Extracted URL as ${link}`);
rp(link)
.then(function(html) {
console.log('Successfully downloaded the site!' +
' Now scraping the data...');
fileData = generateCSV(html, [1, 2]);
console.log('Downloaded table!');

const linkPieces = link.split('/');
if (linkPieces[linkPieces.length - 1] == '') {
linkPieces.pop(linkPieces.length - 1);
}
filename = linkPieces[linkPieces.length - 1].replace('-', '');

fs.writeFile(`App/JS/Resources/Servos/${filename}.csv`,
fileData, function(err) {
if (err) {
console.error('Failed to write file! Do you have access?');
}
console.log(`Saved the file as ${filename}.csv`);
});

uploadButton = document.getElementById('upload');
uploadButton.innerHTML =
`Upload <strong>${filename}.csv</strong>`;
uploadButton.style.display = null;
})
.catch(function(err) {
console.error('An error has occured!' + '\n' +
'Check that you have an active internet connection' + '\n' +
'Additionally, check that you are able to access sites' + '\n' +
'This may be due to you being connected to the robot' + '\n' +
`Recieved error: \n${err}`);
});
} else {
console.error('It seems that your URL is invalid!');
}
}

/**
* Uploads the data stored in fileData through TCP to a listening fileserver
*/
function uploadFile() {
if (fileData == null || fileData == undefined || fileData == '') {
console.error('There is no downloaded file!');
return;
}

client.connect({
port: 5004,
address: '127.0.0.1',
});

client.on('connect', function() {
client.write(`${filename}\n${fileData}`);
console.log('Wrote file to server!');
});

console.log('Uploaded table!');
}
19 changes: 19 additions & 0 deletions App/createServo.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Create a new servo type</title>
</head>
<script type="text/javascript" src="JS/createServo.js"></script>
<link rel="stylesheet" href="CSS/createServo.css">
<body>
<p id="invalid_url" style="display: none">Invalid URL!</p>
<div class="container">
<form>
<input type="text" id="url"></input>
</form>
<button id="download" onclick="getFile()">Download the file!</button>
<button id="upload" onclick="uploadFile()" style="display: none"></button>
</div>
</body>
</html>
21 changes: 21 additions & 0 deletions Server/fileServer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const fs = require('fs');
const net = require('net');
const server = net.createServer();

server.on('connection', function(socket) {
socket.on('data', function(data) {
let fileData = data.toString().split('\n');
const filename = fileData[0].replace('-', '');
fileData.shift();
fileData = fileData.join('\n');

fs.writeFile(`./Driving/Servos/${filename}.csv`, fileData, function(err) {
if (err) {
console.error('Failed to write file! Do you have access?');
}
console.log(`Saved the file as ${filename}.csv`);
});
});
});

server.listen(5004, '');
4 changes: 4 additions & 0 deletions Server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ const commands = {
'Driving': [
'python3',
['-u', './Driving/server.py']
],
'Fileserver': [
'node',
['./fileServer.js']
]
}

Expand Down
21 changes: 4 additions & 17 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,16 @@ function createWindow() {
width: 1600,
height: 1200
});
win.loadFile('App/loading.html');
setTimeout(function() {
win.loadFile('App/index.html');
}, 3000)
// win.loadFile('App/loading.html');
// setTimeout(function() {
win.loadFile('App/createServo.html');
// }, 3000)
// win.loadURL('http://localhost:8080')
win.webContents.openDevTools();

win.on('closed', () => {
win = null;
});
win2 = new BrowserWindow({
width: 1600,
height: 1200
});
win2.loadFile('App/loading.html');
setTimeout(function() {
win2.loadFile('App/charts.html');
}, 3000)
// win.loadURL('http://localhost:8080')

win2.on('closed', () => {
win2 = null;
});
}

app.on('ready', createWindow);
Expand Down
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
"license": "Apache",
"private": false,
"dependencies": {
"electron": "^6.0.2"
"cheerio": "^1.0.0-rc.3",
"cheerio-tableparser": "^1.0.1",
"electron": "^6.0.2",
"eslint-config-google": "^0.13.0",
"request-promise": "^4.2.4"
}
}
Loading

0 comments on commit 258b3cb

Please sign in to comment.