UI for Odrivetool

ok. Thanks for info. This weekend I will try to upgrade my firmware to the newest and will check it out… but this other error that you shared is not UI related.

I might need to tweak some encoder settings. Is your encoder on the motor or after gear reduction? You need to change counts per revolution I think…

Thanks for your advice,though I have solved the problem of encoder yesterday.
Thank you for your hard work to make odrivetool UI better!

Just a little update. I had to redo a setup of odrive board with some motors and update firmware. I solved the problems you listed but after those I discovered plenty of others. I need another session to remap the settings to UI. I will get on it in next couple days.

I really appreciate your hard work! Just take your time. I will try it on my board once you finish and give you feedback

Hey,
So I did some updates to remove errors. In my setup I managed to run through calibration cycle and then control it via velocity, torque, position. But There are still plenty of settings in configuration that needs to be updated. So not sure if that’s of any use yet.
I haven’t used odrive for a while so not sure what it takes to properly calibrate it etc. as I would get certain errors but after rebooting it would fix.
So if specific configs are of interest let me know. But else I think I could finish up writing next version of this app where all configs are detected automatically instead of configuring manually. As I see odrive settings keep changing it would be a bit more future proof.

is this tool ready for us ? I would love to try :slight_smile:

So it’s work in progress.
The first tool was very manual, so it’s just pain to try and keep it up to date. The other dynamic version I was working on I think it was too tedious. Where in order to see any configurations you have to drag and drop it to the window. So just too much clicking, I believe similar issues is with official GUI. It would be nice to have some preconfigured things.
This new version is a bit of both. Once odrive is detected it should appear in the tree view (it will support multiple odrive boards) and once any item is selected it automatically generates all it’s configs. But since config hierarchy is not “pretty” and it’s generated automatically it kinda looks all over the place. But idea is that I don’t keep track of any config variable names etc… So, now I need to add some rules about how things are being placed within the window so nice and tidy, then add a tab with motion controls etc.
Here is a snipped of what it looks like now. ui_odrivetool_2021_05_21

I still need few more evenings to make it all tidy and functional. I was thinking also of adding a feature where if there is a requirement to see multiple windows at the same time, we can make that window to pop out. Like if we want to monitor some motion control and change settings at the same time.

I much prefer this style of tool to the official GUI. Its more responsive, more hackable, and just a better layout; nice work!

It’s really hard chasing unstable API’s, especially when the changelogs are cryptic. I know because I spent a week working on a GUI in DearPyGui, right before the last odrive firmware update that changed around most of the API (for the better, in my opinion). Might be worth your time to make an introspective API tree generator. Something that queries up an object, determines if it is an atomic, a node, or a function, then recurses it’s children if their are any. Throw all of these into your current layout setup under a tree view, and no more chasing API changes. I haven’t done any heavy python introspection in a few years, but I might take a crack at it this afternoon and see if I can come up with something sane.

So, at the moment that’s exactly how it would work. First I check if it’s read or read/write variable and then based of type (bool, float, uint, etc.) I choose the layout. But there are a lot of configs just having stuff in tree view clutters things (like in this old one https://vimeo.com/322372659). But if I just generate all things in the window it’s also kinda too many. Here is how it looks if I expand all axis items into a window
ui_odrivetool_2021_05_24_1 all sub groups go to new column, so it becomes a lot of scrolling.
I tried grouping things here. So this is how it looks now ui_odrivetool_2021_05_24_2 smaller columns are stacked. but it’s like a matrix of numbers. Maybe this is good enough, but based on today’s session I think It’s ok if I create some custom visuals for high level groups like within axis motor, controller or encoder.
So basically I can do custom UI for those groups without actually touching variables within. Those are still automatically generated.
So I can leave it the way it is or move it to tabs or whatever. Any ideas welcome…
Today I will finish up and make buttons functional. And then in the next session add graphs for controls.

Ah good, glad that I’m not too rusty to have decent dev ideas =D fitting everything in so it’s both accessible and uncluttered is hard with so much going on. It might be good to recurse the tree widget all the way down. For example, for axis0’s subtree, expose:

error = 0x0001 (int)
step_dir_active = False (bool)
current_state = 1 (int)
requested_state = 0 (int)
loop_counter = 4095597 (int)
lockin_state = 0 (int)
is_homed = False (bool)

in read/write fields as appropriate, and:

watchdog_feed()
clear_errors()

as buttons, and:

config:
fet_thermistor:
motor_thermistor:
motor:
controller:
encoder:
sensorless_estimator:
trap_traj:
min_endstop:
max_endstop:

as subtrees.

I haven’t played with pyQT much, but I’m guessing that style might simplify the autogeneration of the whole tree structure, and give you more breathing room for fun custom UI stuff like custom charting and specific control panels.

Also, I just burnt out my odrive today, so I won’t be able to do much in the way of testing for a week or so lol.

Burning out odrive boards sucks… how did you managed to do that?

Today, I did not change the UI much. I added few things like function buttons at the top always stay as we scroll and made changing configurations functional. So, basically if we change any value in gets highlighted with yellow and then we need to press “apply” button to apply the changes to the board.

Some other function buttons are not functional yet. For the graph I just started migrating code from the previous version.

But to come back to UI layout I totally agree with your suggestion, in this way the window won’t get cluttered/filled up , but we just need to be more active on the tree view and know that even high level tree items have configs.

First I will finish up to make it fully functional and then try to adjust the layout like suggested as for me it won’t change much how things work as all backed would be the same just choices on how tree is being generated etc.

Here is the current version with highlighting ui_odrivetool_2021_05_25

Left it running in what I thought was an idle state, ended up getting delayed a while, and when I came back the whole board was super hot and unresponsive, motor was too hot to touch, plastic mount was melted etc. I had been playing around with mirroring and PID settings, so I imagine I must’ve left one motor bouncing back and forth trying to match the other, but without enough dampening to ever hit a stable setpoint. User error, of course haha.

A note on the plotting. I did a little mini control panel for odrive using DearPyGui a while back, and the plotting turned out really nice using a list of plottable variables with radio buttons for “off”, “graph0”, “graph1”. Then I could arbitrarily plot any variable, from either motor, against another variable. This ended up being nice for phase shifted movements, comparing current draw between them, etc. It was really easy in DPG (because DPG is immediate mode GUI, dynamic changes like that are a breeze), and I found it quite helpful. If you are migrating your plotting, might be worth adding a note to look into selectable variables for traces.

That’s a great point about discoverability for high level configurations. From what I can tell, every node that has subnodes also has, at the least, read-only variables, so every node will have something to display on the main canvas.

Highlighting changes is really a clutch idea. I’ve worked with industrial control systems that don’t do differential highlighting, and it can be a nightmare of “what was it that I changed?”, and “what state is the system in?”.

Another thought that comes to mind, I haven’t seen anything from the ODrive team that indicates the API is stable now. One of the pain points I’ve run into with control systems over the years is Hardware → Firmware → Software version incompatibilities. If you are planning to upgrade your odrive, either in hardware or firmware, it may save you a headache down the line to have a plan for dealing with breaking API changes, if there’s not one already. The auto-generated tree is probably the greatest asset for dealing with this, but there’s also function signatures and enums to deal with, ie “CTRL” → “CONTROL”, etc.

Really wish I could help more with this than just throwing spaghetti at the wall to see what sticks, but after having poked around the codebase quite a bit, I feel I’d be more a nuisance than an asset for actually writing code.

2 Likes

[New version] Ready to be used and abused Povilas / UI_odrivetool · GitLab
Please give some feedback and report any bugs.

It took me a while as I actually had a little incident when I did not commit the code and reset the repository so I even had to start hours before of what was posted in my last video update…
Since I had to redo a bunch of code I thought I might implement your suggested changes right away.
So now the treeview is as suggested it gives more sub-levels for the tree so more selections there and the main window is no so cluttered.

Besides the buttons at the top Apply (send changes to the odrive), save&erase config and reboot the only other button I made functional is clear_errors() at axis level. I am not sure if other buttons are really useful. So I haven’t made them functional yet. So let me know what you think about them.

The other bigger update is that it now supports multiple boards! I am not sure how to do it so it detects all boards automatically, as I only made it to work when you select a specific number, so at the top you first select how many boards are connected, click connect and it will search until it finds that number.

Since no config is manually defined it works pretty well with older versions too. I borrowed another odrive board from a colleague and his HW and FW versions are way older but the config worked just fine!

Then also I added the graph. It’s very similar like last time, I just added the basics so at least it’s functional. So the way it works that if you have multiple boards, first you select odrive from the treeview and then it opens another pop up window for that odrive board.

Here is the video where I demonstrate most of these features. And note where I show different boards about different settings available.

So since my last time I properly used odrive I wasn’t aware of input mode feature so at the moment in the graph settings are only for INPUT_MODE_PASSTHROUGH . But I am planning to implement input mode selection in the graph too. All settings are accessible via regular settings thou…

Also, I was thinking of either if we have more boards connected I could open new window for graph and let it stay. meaning multiple windows for multiple odrive boards… or maybe reuse the same and then stack them within same plot widgets.
Maybe then it’s more worth while to add more selection options of what to display.

And in graph pop up window at the bottom I added some error code translations, but I just reused ones that I made 2 years ago, so if there were any changes those might be out of date. I am planned to do a revision on those too…

Anyways, at least it’s functional now. Let me know what you think!

FIY. With new odrivetool this doesn’t work. I trying to understand the underlying changes, I thought few things I can just fix up quickly, but even the main objects that I used on generating all the configs doesn’t exist anymore. Got to find alternative ways…

New odrivetool? Which revision / branch is it on? Those sound like some large breaking changes…

Just released v0.5.2. . I mean they changed a bunch of variable names again all over the place but these would be no problem as we generated things automatically. But now objects that I used to iterate though are not there anymore.

I wrote something similar with tkinter so it can run on pi a year ago and after v0.5.2 it do not work anymore as well. I use “x._remote_attributes.items()” grab all the data to iterate through, but since 0.5.2 moved to new libfiber implementation this method no longer work. I still try to find the method to use with the newer libfiber object, I will be very much appreciate if someone can give me a pointer or suggestion what to do. Thanks!

1 Like

I asked the same question at https://discourse.odriverobotics.com/t/re-firmware-0-5-2-release-thread/7172?u=tinker_inc

To iterate over property members of an object you can look at how odrivetool fetches a configuration snapshot:

So in UI I made I use the same thing

To get attributes odrivetool_UI.py · odrive_52 · Povilas / UI_odrivetool · GitLab
drive_dict = self.get_dict(my_drive, my_drive, True) with get_dict and obj_to_path

and to see if it’s read-only or read-write

Use hasattr(exchange_property, “exchange”) to see if it’s read-write .

1 Like

@tinker_inc Thanks so much for responding! I will follow your suggestion and give it a try.

Hello, look nice, is there any update and where to find it ?