mirror of
https://github.com/odriverobotics/ODrive.git
synced 2026-08-20 22:14:34 +08:00
Fixes for the crashes caused by disconnecting one odrive and connecting another while the GUI is open. Fixed numerical inputs to accept "0".
This commit is contained in:
+24
-11
@@ -58,8 +58,12 @@ def discovered_device(device):
|
||||
while globals()['inUse']:
|
||||
time.sleep(0.1)
|
||||
globals()['odrives'][odrive_name] = device
|
||||
globals()['odrives_status'][odrive_name] = True
|
||||
print("Found " + str(serial_number))
|
||||
print("odrive list: " + str([key for key in globals()['odrives'].keys()]))
|
||||
# tell GUI the status of known ODrives (previously connected and then disconnected ODrives will be "False")
|
||||
socketio.emit('odrives-status', json.dumps(globals()['odrives_status']))
|
||||
# triggers a getODrives socketio message
|
||||
socketio.emit('odrive-found')
|
||||
|
||||
def start_discovery():
|
||||
@@ -68,9 +72,12 @@ def start_discovery():
|
||||
shutdown = fibre.Event()
|
||||
fibre.find_all("usb", None, discovered_device, shutdown, shutdown, log)
|
||||
|
||||
def handle_disconnect():
|
||||
def handle_disconnect(odrive_name):
|
||||
print("lost odrive")
|
||||
#socketio.emit('odrive-disconnected')
|
||||
globals()['odrives_status'][odrive_name] = False
|
||||
# emit the whole list of odrive statuses
|
||||
# in the GUI, mark and use status as ODrive state.
|
||||
socketio.emit('odrives-status', json.dumps(globals()['odrives_status']))
|
||||
|
||||
@socketio.on('findODrives')
|
||||
def getODrives(message):
|
||||
@@ -115,8 +122,9 @@ def get_odrives(data):
|
||||
odriveDict = {}
|
||||
#for (index, odrv) in enumerate(globals()['odrives']):
|
||||
# odriveDict["odrive" + str(index)] = dictFromRO(odrv)
|
||||
for key in globals()['odrives'].keys():
|
||||
odriveDict[key] = dictFromRO(globals()['odrives'][key])
|
||||
for key in globals()['odrives_status'].keys():
|
||||
if globals()['odrives_status'][key] == True:
|
||||
odriveDict[key] = dictFromRO(globals()['odrives'][key])
|
||||
globals()['inUse'] = False
|
||||
emit('odrives', json.dumps(odriveDict))
|
||||
|
||||
@@ -126,10 +134,11 @@ def get_property(message):
|
||||
# will be {"path": "odriveX.axisY.blah.blah"}
|
||||
while globals()['inUse']:
|
||||
time.sleep(0.1)
|
||||
globals()['inUse'] = True
|
||||
val = getVal(globals()['odrives'], message["path"].split('.'))
|
||||
globals()['inUse'] = False
|
||||
emit('ODriveProperty', json.dumps({"path": message["path"], "val": val}))
|
||||
if globals()['odrives_status'][message["path"].split('.')[0]]:
|
||||
globals()['inUse'] = True
|
||||
val = getVal(globals()['odrives'], message["path"].split('.'))
|
||||
globals()['inUse'] = False
|
||||
emit('ODriveProperty', json.dumps({"path": message["path"], "val": val}))
|
||||
|
||||
@socketio.on('setProperty')
|
||||
def set_property(message):
|
||||
@@ -194,7 +203,7 @@ def postVal(odrives, keyList, value, argType):
|
||||
else:
|
||||
pass # dont support that type yet
|
||||
except fibre.protocol.ChannelBrokenException:
|
||||
handle_disconnect()
|
||||
handle_disconnect(odrv)
|
||||
except:
|
||||
print("exception in postVal")
|
||||
|
||||
@@ -210,7 +219,7 @@ def getVal(odrives, keyList):
|
||||
else:
|
||||
return RO.get_value()
|
||||
except fibre.protocol.ChannelBrokenException:
|
||||
handle_disconnect()
|
||||
handle_disconnect(odrv)
|
||||
except:
|
||||
print("exception in getVal")
|
||||
return 0
|
||||
@@ -235,7 +244,7 @@ def callFunc(odrives, keyList):
|
||||
if isinstance(RO, fibre.remote_object.RemoteFunction):
|
||||
RO.__call__()
|
||||
except fibre.protocol.ChannelBrokenException:
|
||||
handle_disconnect()
|
||||
handle_disconnect(odrv)
|
||||
except:
|
||||
print("fcn call failed")
|
||||
|
||||
@@ -252,7 +261,11 @@ if __name__ == "__main__":
|
||||
import odrive.utils # for dump_errors()
|
||||
import fibre
|
||||
|
||||
# global for holding references to all connected odrives
|
||||
globals()['odrives'] = {}
|
||||
# global dict {'odriveX': True/False} where True/False reflects status of connection
|
||||
# on handle_disconnect, set it to False. On connection, set it to True
|
||||
globals()['odrives_status'] = {}
|
||||
globals()['discovered_devices'] = []
|
||||
# spinlock
|
||||
globals()['inUse'] = False
|
||||
|
||||
@@ -56,9 +56,6 @@
|
||||
:axis="axis.name"
|
||||
:odrives="odrives"
|
||||
></Axis>
|
||||
<!--<div class="odrive-status">
|
||||
ODrive:{{ODriveConnected}}
|
||||
</div>-->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -129,22 +126,6 @@ export default {
|
||||
currentDash: function () {
|
||||
return this.$store.state.currentDash;
|
||||
},
|
||||
ODriveConnected: function () {
|
||||
// if server and odrive disconnected, disconnected
|
||||
// if server connected and odrive disco, connecting
|
||||
// if server and odrive connected, connected
|
||||
let ret;
|
||||
if (this.$store.state.serverConnected && this.$store.state.ODriveConnected) {
|
||||
ret = "connected";
|
||||
}
|
||||
else if (this.$store.state.serverConnected && !this.$store.state.ODriveConnected) {
|
||||
ret = "connecting...";
|
||||
}
|
||||
else {
|
||||
ret = "disconnected";
|
||||
}
|
||||
return ret;
|
||||
},
|
||||
samplingText: function () {
|
||||
let ret;
|
||||
if (this.$store.state.sampling) {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div
|
||||
class="axis"
|
||||
@click.self="showError = !showError;"
|
||||
:class="{ noError: !error, error: error}"
|
||||
:class="{inactive: !connected, noError: !error, error: error}"
|
||||
>
|
||||
{{ axis }}
|
||||
<div v-show="showError" class="error-popup card" @click.self="showError = !showError">
|
||||
@@ -110,6 +110,9 @@ export default {
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
connected() {
|
||||
return this.$store.state.ODrivesConnected[this.axis.split('.')[0]];
|
||||
},
|
||||
axisErrorMsg() {
|
||||
let retMsg = "none";
|
||||
let errCode = this.axisErr;
|
||||
@@ -229,14 +232,18 @@ export default {
|
||||
created() {
|
||||
// set up timeout loop for grabbing axis error values
|
||||
let update = () => {
|
||||
fetchParam(this.axis + ".error");
|
||||
fetchParam(this.axis + '.motor.error');
|
||||
fetchParam(this.axis + '.controller.error');
|
||||
fetchParam(this.axis + '.encoder.error');
|
||||
this.axisErr = getVal(this.axis + '.error');
|
||||
this.motorErr = getVal(this.axis + '.motor.error');
|
||||
this.controllerErr = getVal(this.axis + '.controller.error');
|
||||
this.encoderErr = getVal(this.axis + '.encoder.error');
|
||||
// Do we have an active connection to the ODrive that contains this axis?
|
||||
if (this.$store.state.ODrivesConnected[this.axis.split('.')[0]]) {
|
||||
fetchParam(this.axis + ".error");
|
||||
fetchParam(this.axis + '.motor.error');
|
||||
fetchParam(this.axis + '.controller.error');
|
||||
fetchParam(this.axis + '.encoder.error');
|
||||
this.axisErr = getVal(this.axis + '.error');
|
||||
this.motorErr = getVal(this.axis + '.motor.error');
|
||||
this.controllerErr = getVal(this.axis + '.controller.error');
|
||||
this.encoderErr = getVal(this.axis + '.encoder.error');
|
||||
}
|
||||
// ODrive not connected
|
||||
setTimeout(update, 1000);
|
||||
}
|
||||
update();
|
||||
@@ -270,4 +277,8 @@ export default {
|
||||
color: black;
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
.inactive {
|
||||
color: grey;
|
||||
}
|
||||
</style>
|
||||
@@ -40,7 +40,7 @@ export default {
|
||||
methods: {
|
||||
newVal: function (e) {
|
||||
let val = parseMath(e.target.value);
|
||||
if (val != false) {
|
||||
if (val !== false) {
|
||||
this.value = val;
|
||||
console.log("input = " + e.target.value + ", val = " + this.value);
|
||||
this.$store.commit("setActionVal", {dashID: this.dashID, actionID: this.id, val: this.value});
|
||||
|
||||
@@ -47,8 +47,9 @@ export default {
|
||||
putVal: function (e) {
|
||||
let keys = this.path.split('.');
|
||||
keys.shift();
|
||||
console.log("input recieved: " + e.target.value);
|
||||
let val = parseMath(e.target.value);
|
||||
if (val != false) {
|
||||
if (val !== false) {
|
||||
putVal(keys.join('.'), val);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -37,7 +37,7 @@ export default {
|
||||
setBR(e) {
|
||||
console.log("from setBR " + e.target.value);
|
||||
let val = parseMath(e.target.value);
|
||||
if (val != false) {
|
||||
if (val !== false) {
|
||||
this.brake_resistance = val;
|
||||
let configStub = undefined;
|
||||
configStub = {
|
||||
|
||||
@@ -26,7 +26,7 @@ export default {
|
||||
methods: {
|
||||
setCPR(e) {
|
||||
let val = parseMath(e.target.value);
|
||||
if (val != false) {
|
||||
if (val !== false) {
|
||||
this.cpr = val;
|
||||
let configStub = undefined;
|
||||
if (this.data.axis == "axis0") {
|
||||
|
||||
@@ -27,7 +27,7 @@ export default {
|
||||
methods: {
|
||||
setCPR(e) {
|
||||
let val = parseMath(e.target.value);
|
||||
if (val != false) {
|
||||
if (val !== false) {
|
||||
this.cpr = val;
|
||||
let configStub = undefined;
|
||||
if (this.data.axis == "axis0") {
|
||||
|
||||
@@ -100,7 +100,7 @@ export default {
|
||||
},
|
||||
setVelocityLimit(e) {
|
||||
let val = parseMath(e.target.value);
|
||||
if (val != false) {
|
||||
if (val !== false) {
|
||||
this.vel_limit = parseFloat(e.target.value);
|
||||
this.vel_set = true;
|
||||
this.sendConfig();
|
||||
@@ -108,7 +108,7 @@ export default {
|
||||
},
|
||||
setCurrentLimit(e) {
|
||||
let val = parseMath(e.target.value);
|
||||
if (val != false) {
|
||||
if (val !== false) {
|
||||
this.current_lim = parseFloat(e.target.value);
|
||||
this.current_set = true;
|
||||
this.sendConfig();
|
||||
|
||||
@@ -6,11 +6,17 @@ import * as socketio from "../comms/socketio.js";
|
||||
// given a path like "odrive0.axis0.config.blah", return the value
|
||||
export function getParam(path) {
|
||||
let keys = path.split('.');
|
||||
let odriveObj = store.state.odrives;
|
||||
for (const key of keys) {
|
||||
odriveObj = odriveObj[key];
|
||||
if (store.state.ODrivesConnected[keys[0]]) {
|
||||
let odriveObj = store.state.odrives;
|
||||
for (const key of keys) {
|
||||
odriveObj = odriveObj[key];
|
||||
}
|
||||
return odriveObj;
|
||||
}
|
||||
else {
|
||||
console.log("getParam for " + path + " is for disconnected ODrive");
|
||||
return undefined;
|
||||
}
|
||||
return odriveObj;
|
||||
}
|
||||
|
||||
// wrapper for val field
|
||||
@@ -51,10 +57,15 @@ export function parseMath(inString) {
|
||||
|
||||
export function putVal(path, value) {
|
||||
console.log("path: " + path + ", val: " + value + ", type: " + typeof value);
|
||||
socketio.sendEvent({
|
||||
type: "setProperty",
|
||||
data: {path: path, val: value, type: typeof value}
|
||||
})
|
||||
if (store.state.ODrivesConnected[path.split('.')[0]]) {
|
||||
socketio.sendEvent({
|
||||
type: "setProperty",
|
||||
data: {path: path, val: value, type: typeof value}
|
||||
});
|
||||
}
|
||||
else {
|
||||
console.log("requesting " + path + " from disconnected odrive")
|
||||
}
|
||||
}
|
||||
|
||||
// path is path to function, args is list of parameters
|
||||
|
||||
+22
-13
@@ -21,7 +21,7 @@ export default new Vuex.Store({
|
||||
axes: Array,
|
||||
odriveServerAddress: String,
|
||||
serverConnected: Boolean,
|
||||
ODriveConnected: false,
|
||||
ODrivesConnected: Object,
|
||||
serverOutput: [],
|
||||
dashboards: [
|
||||
{
|
||||
@@ -95,6 +95,13 @@ export default new Vuex.Store({
|
||||
state.odriveConfigs['writeAble'] = payload.writeAble;
|
||||
state.odriveConfigs['writeAbleNumeric'] = payload.writeAbleNumeric;
|
||||
},
|
||||
setODrivesStatus(state, obj) {
|
||||
// obj is {"odriveX": true/false}
|
||||
for (const odrive of Object.keys(obj)){
|
||||
state.ODrivesConnected[odrive] = obj[odrive];
|
||||
console.log(state.ODrivesConnected);
|
||||
}
|
||||
},
|
||||
setAxes(state, axes) {
|
||||
state.axes = axes;
|
||||
},
|
||||
@@ -163,9 +170,6 @@ export default new Vuex.Store({
|
||||
setServerStatus(state, val) {
|
||||
state.serverConnected = val;
|
||||
},
|
||||
setODriveConnected(state, val) {
|
||||
state.ODriveConnected = val;
|
||||
},
|
||||
removeCtrlFromDash(state, obj) {
|
||||
// obj is {dash: dashID, path: control path}
|
||||
for (const dash of state.dashboards) {
|
||||
@@ -325,7 +329,6 @@ export default new Vuex.Store({
|
||||
type: "odrive-found",
|
||||
callback: () => {
|
||||
console.log("odrive-found recieved from server");
|
||||
context.commit("setODriveConnected", true);
|
||||
context.dispatch("getOdrives");
|
||||
}
|
||||
})
|
||||
@@ -370,15 +373,21 @@ export default new Vuex.Store({
|
||||
});
|
||||
socketio.addEventListener({
|
||||
type: "odrive-disconnected",
|
||||
callback: () => {
|
||||
console.log("odrive disconnected");
|
||||
context.commit("setODriveConnected", false);
|
||||
console.log("restarting server...");
|
||||
window.ipcRenderer.send('kill-server');
|
||||
window.ipcRenderer.send('start-server');
|
||||
context.dispatch('setServerAddress', context.state.odriveServerAddress);
|
||||
callback: (odrive_name) => {
|
||||
console.log(odrive_name + " disconnected");
|
||||
//console.log("restarting server...");
|
||||
//window.ipcRenderer.send('kill-server');
|
||||
//window.ipcRenderer.send('start-server');
|
||||
//context.dispatch('setServerAddress', context.state.odriveServerAddress);
|
||||
}
|
||||
})
|
||||
});
|
||||
socketio.addEventListener({
|
||||
type: "odrives-status",
|
||||
callback: (odrives_status) => {
|
||||
console.log("From odrives-status msg " + odrives_status);
|
||||
context.commit('setODrivesStatus', JSON.parse(odrives_status));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user