Picking up from the last log, I had good working hardware that was able to send raw data from the LDCs to my PC, but I wasn't sure what to do with that data. In comes the software. I knew this problem would be a hard one. In one of my earlier project logs I mentioned using the Stewart platform as a kinematic model for the device.
This sounds great on paper until you try to go and actually solve the direct kinematics of a Stewart platform. In direct kinematics, you know the lengths of the legs and try to solve for platform position, rather than inverse kinematics where you know what platform position you want and solve for leg lengths. I am but a humble electrical engineer and this world is extremely foreign to me, but I dove in anyways hoping to find some example code or something that I could port to my application. All I found was disappointment and papers with names such as "Forward Displacement Analysis of a General 6-3 Stewart Platform Using Conformal Geometric Algebra". Much to my and probably your dismay, I have no interest in learning all the prerequisites necessary to even begin parsing a paper like that. And so... the project sat. I thought more and more about it, but wasn't sure who to reach out to for help with this problem.
And funny enough, my rescue came from the last place I expected it... someone doing the same project as me! When I first started this project several months ago, I thought I was alone, but just in that short time, at least 3 other projects with the same goal have popped up. My solution came from the SpaceFox, which claims to be the first true DIY 6DOF spacemouse. (and while my pride is a bit hurt, I think he may be correct). I have no idea how he came up with his solution for kinematics, but they seem fairly intuitive and would be easy for your average microcontroller to compute. I have taken these kinematics, made some slight modifications, and implemented them in my code. Much to my surprise, they worked! It took a bit more debugging than that makes it sound, but still! No nasty univariate polynomial of the 40th order! After seeing this, I felt reenergized about the project and started making more progress (including publishing the last update).
My next goal was to visualize the translation and rotation. I dug in more to see what would be necessary to get the serial data to actually interface with Solidworks. I didn't like the answer: it seems like I will have to write a custom C++ application in order to do the interfacing. I wasn't feeling up to that to start, so I did the next best thing - write something scrappy in Python! If you've never heard of it, there's a wonderful game engine known as Ursina that's written to with nice Python bindings and is dead simple to get started with. I merely glued together pyserial and Ursina with the script below to create a working result!
import serial
from ursina import *
app = Ursina()
ser = serial.Serial('COM5', 115200)
cube = Entity(model='cube', texture='white_cube', scale=2, collider='box')
def my_update():
line = ser.readline() # get the serial data
line = line.decode('ascii').rstrip().split(', ')
coil_data = [float(i) / 200 for i in line] # break apart the data, scale it down
print(f'vals: {coil_data}')
coil_data = [0 if abs(i) < 0.2 else i for i in coil_data] # filter out small drift
x, y, z, rx, ry, rz = coil_data
cube.position = cube.position + ((x - rx * .3) / 2, z / 14, (-y - ry * .3) / 2) # apply rotational correction
cube.rotation = cube.rotation + (rx * 1.5, rz * 2, -ry * 1.5)
cube.update = my_update
EditorCamera()
app.run()
Check it out!
As you can see, it works!!! But, it is certainly not without its issues. If you look closely at the script above, you'll notice that the position data is having rotational correction applied to it. I'm not sure what the technical name for this is, but I imagine it's something like "inter-axis interaction". My understanding so far is that this is likely the mouse doing everything right, and this interaction is actually a result of the mechanical design. The problem here (I think) is that the platform that the kinematics are being calculated for is not centered at the middle of the knob, but rather the middle of the 3 coins. The mouse knob rotates around roughly the "middle of the mouse", which means that when you roll or pitch the knob, you're actually kicking out the "coin platform" in the opposite direction your rolling/pitching in. This leads to translation when you expect only rotation. For now, I've gotten in tuned out well enough, but it is something I hope to explore deeper in the future.
And with that, I'm left with 4 things I'd like to work on going forward, listed in priority:
- Get a program working that can feed the data into Solidworks so I can fulfill the original pledge I made in log 0
- Setup a repository so others can see how bad my code is (and possibly build your own mouse, though I don't recommend doing that quite yet)
- Respin the PCB with a few changes - different MCU, different coil caps, add INTB pin support, more test points, maybe external 40 MHz osc for improved accuracy
- Do some signal processing/filtering on the coil data to further refine the feel of the mouse
Lastly, I want to leave off on a note about what I want this project to be, especially now that there are a plethora of other options out there. I want the OS3M mouse to be the simplest option, because in my mind, simpler is almost always better. I want it to be as easy as either you buy a PCB from me on Tindie or build your own, 3D print the parts, use 9 M3 fasteners to put everything together, snap in 3 dimes, and away you go. I'm targeting a BOM where you only have to buy 2 things (or maybe even just 1 if I include the fasteners with the PCBs), 3D print the rest, and bam you have a CADmouse for less than $20. IMO, that's the kind of thing I could see making a difference in schools or other areas where buying the name brand is off the table. Let me know what your thoughts are!
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.
Excellent progress! I can't wait to build one!
Are you sure? yes | no