It's been quite some time since I last wrote a project log, however this was mostly caused by shipping problems of my new actuator PCBs as well as some exams and projects going on on my university.
I do not like to waste my time so in the meantime I started working on a small size dyno for characterizing small motors (without the gearbox, so the load capacity is not very big). I made my own dynamic torque transducer and a small frame for the sensor. The motors (absorber and test motor) are mounted on each side of a small plate and their shafts are connected to the torque sensor's shaft through couplers. As I was sick of waiting for the PCB's to arrive I decided to mill a similar 2-layer board with a chopper functionality, to make it possible to operate as an absorber (not only a motor controller). This functionality is going to be used on the absorber motor in order to dissipate the energy produced by the motor under test. Besides I added USB connection for exchanging the data with the computer and a communication module for communicating with torque transducer. I found out that I was missing a pullup resistor on a MOSI line of the MOSFET driver, so it's good that I tested it before reordering the PCBs.
A few photos of the prototype board:
I'm still working on the code, but for now I managed to spin the motor, read currents and read velocity in a slightly different manner than before. I'm using the method of measuring time between encoder pulses using two timers. This was introduced on Ben Katz's blog a few years back. However in contrast to the software filtering technique he has used, I used the FMAC peripheral. This is a new peripheral that comes with the G4 series and it seems to work just fine. It is a simple FIR filter (moving average) but it seems to be a bit faster than it's software equivalent.
I still haven't received my new brushless controller PCBs... I guess I've ordered them in the least appropriate time ;)
That is why I’ve been working on something else. Having remembered how difficult upgrading 12 controllers mounted on a robot was, I decided to write a custom CAN bootloader. I didn’t want to use the built in CAN bootloader, because it cannot be customized and as far as I know it has some bugs. I found some very helpful information online, as I was not quite familiar with the booloader convention:
-Josh's Pieper's blog: https://jpieper.com/2020/01/24/can-bootloader-for-moteus-r4-x/
-Kevin's Cuzner's blog: http://kevincuzner.com/2018/06/28/building-a-usb-bootloader-for-an-stm32/
After reading these guys’ work and going through some source codes I had a fundamental understanding of the whole bootloading process.
The code was tested on a previous version of my controller and a f476 nucelo board serving as a USB <=> CAN converter. The converter is used as a translator between the serial data sent from the computer and CAN bus. An additional byte in the serial frame indicates a CAN command ID. The rest is just data.
The bootloading procedure:
When the slave device is in bootloader mode it can receive a few different CAN commands. The host computer executes a python script, which first opens a firmware file and sends a command to the destination device about the size of memory to erase. After a successful erase process the slave device sends an "ok" message and the process of firmware download is started. The script sends chunks of firmware to the slave device. After a preset number of bytes is sent, the computer script sends a CRC code and pauses. If the code matches with the slave's internally computed code another "ok" message is sent to the master device. The whole process repeats until the end of the *.bin file is reached. In the end the computer transmits a reset command, and the new firmware is started.
Bootloader mode is entered only when the soft reset occurred and the master device sent an appropriate command within a 1,5 second time window. For now any other reset causes an immediate jump to the user’s code. I find this quite useful, because when the drivers are powered on I want them to start executing the firmware without any delay, and the bootloader mode can be easily entered through a special CAN frame resulting in soft reset. The bootloader is still in development stage, as I'm still waiting for the PCBs.
I came across one mistake on the CAN<=>USB converter PCB. The new G4 series is capable of using boot0 pin as any other GPIO. Without much thinking, I remmaped CAN FD interface to the PA8 (boot0) /PA9 pins. This resulted in entering the bootloader mode each time the device was powered on and a normal startup was not possible (the rxd pin of the transceiver is pulled high when the bus is recessive). A quick fix was an NPN transistor between the rxd and gnd, with a small capacitor on it's base connected to the 3.3V rail. When the voltage is applied the empty capacitor is draining current and thus opening the NPN transistor which, for a really small period of time, shorts the PA8 pin to the ground. When the capacitor is charged up the transistor opens, and does not interfere with the communication process. In the second revision I'm just going to use the dedicated standby pin of the transceiver ;)
Another thing I wanted to mention is the cnc milling machine I’ve been working on for a couple months now. It was meant to mill small parts for my walking robots, mostly aluminum and plastics. The working area is about 300x300x130mm, so I’m able to mill even medium size parts such as robot’s leg fragments. For now I have only tested it in laminate and PA9 aluminum (which is an excellent material for milling). I still have to replace the supported shafts on the Z axis with...Read more »
This time I’d like to focus on the new design of my brushless motor controller. The previous one, although it worked, had a lot of drawbacks. In this revision, I wanted to fix all the issues that were found in the first prototype:
-fix the shunt sensing paths - obligatory kelvin connections
-DRV8232RS (with internal buck converter) instead of DRV8323S - in order to power the device from the DC bus.
-use ceramic capacitors for DC bus.
-use FDCAN transceiver
-use the latest STM32G431 microcontroller as it has many hardware features supporting motor control and FDCAN peripheral
-reduce the size and make it rectangular for easier mounting
-single side component placement on a 4 layer board, hopefully with semi-automatic soldering using a stencil, solder paste and a reflow oven.
I believe the design came out very well. The four layer board is 33x33mm with a height of about 3-4 mm (where the connectors are the highest points). There are a few good practices I stumbled upon on the Internet that I’d like to mention. I do not think they are crucial for the device to operate correctly, however, it is good to know a few basic rules for future reference.
As I said earlier, above guidelines are considered good practices in designing a PCB layout, while not being crucial for basic circuits.
One thing I’m concerned about is the DC bus of the motor driver. Inspired by Benjamin Katz’s design and other small-size controllers I decided to use ceramic capacitors as well. Diving deeper in their specs I came across many characteristics of the capacitance vs dc bias voltage (https://community.cypress.com/docs/DOC-15088). A...Read more »
In this entry, I would like to describe my struggle with the dynamic model of the quadruped. Based on two articles from MIT, IIT and mostly by changing the code available on the MIT’s repository for Cheetah robots I could run the Balance Controller in the VREP simulation program. Generally, a simplified mathematical model of the quadruped is presented as a cost function and then is solved by QPOASES solver in order to get the forces that have to be applied on each leg tip.
The code is written in C++ and communicates with VREP by ROSinterface. The communication is synchronized, meaning the C++ code waits for the simulation to complete a single step (the computer I ran it on is really old and slow).
The simulation model is created from imported SolidWorks Parts. They are modified by the simulation software to minimize the triangle count and thus make the simulation execution time shorter. Joints – special parts available in the simulation can act as passive joints or motors with different control loops. In my case, all the joints were set to torque mode. Having the model prepared, I created the simulation script responsible for controlling the torque on each motor (PD controller) and ROS communication. My assumption was to make the simulation script mimic the software running on each of the motor controllers. This allowed to separate the high level solver code and low level motor drivers software in the same way it is implemented on a real robot.
While trying to run the original Balance Controller, I stumbled upon a few problems. First, I had different zero-angle positions and angle increment directions compared to the minicheeta (cheetach III ?) robot. It was not possible to run the code without modifications.
I decided to check each component of the simulation separately. First, I checked if my leg Jacobian is derived properly by simply commanding a 1N of force in each axis and observing the reaction of the leg. The position were updated as the leg moved under the influence of joint torques. The next main problem were the coordinate frames of the legs. I did not know if there are four different coordinate frames (if so how are they oriented?) or the leg tip’s positions are expressed in the body frame. I used the body frame for that purpose.
Once that was settled up, I created a script in vrep that could visualize the forces acting on the end effectors of each leg. That helped a lot while debugging. I could easily determine if I’m computing the right placement of each joint (forward kinematics) and if the end effector is in the right spot. It was the time when I saw a problem with yaw angle. As long as the robot’s coordinate frame was aligned with the world frame, the model seemed to work. However, when the yaw angle was changed the robot kept losing the stability. It turned out to be an issue with the rotation matrix about yaw axis. The problem was that the authors of the code wanted to express everything in the world frame, whereas I tried to do it in the body frame. After fixing this last issue, the model started to work as expected. Right now I’am able to command roll, pitch and yaw angles as well as translations (through whole body PD controller). Below you can see two videos of the quadruped simulation (I recorded it a few weeks back, and I wasn’t planning to post it, so sorry for the poor quality)–I hope they’ll help to visualize the idea.
There is a lot going on right now with the motor drives. I’ve found a major bug in the software, and I’m also designing a newer improved version of the BLDC controllers. I hope I’ll write about them soon.
See You ;)
This time I’d like to tell you a bit more about the mechanical aspects of the robot. The most interesting parts of each quadruped are undoubtedly the actuators. As I mentioned earlier the idea came from a project by Paul Gould. I got interested in cycloidal drives as I could easily prototype them on my 3d printer. I decided to integrate the actuators completely in the robot’s structure in order to save some space. The leg construction assumes it can be milled from a 7mm plate of material (this dimension is dictated by the width of a single bearing). Moreover I decided to put all the motors (which are quite heavy in comparison to the rest of leg) as far as possible form the leg tip. In that way it is possible to minimize the leg inertia and thus make the leg more agile. Many quadruped designers also claim that when the leg inertias are low enough, it is possible to neglect them in the dynamical model of the robot.
The shape of the cycloids was generated in the SolidWorks program using formulas found on the internet. Hole placement, the eccentricity of the cam (crankshaft?), outer pin count and diameter was computed using one of the online calculators. Knowing all the needed parameters the gearbox was 3d-printed and put together. Below You can see the 3d model of the leg.
Figure 1. 3D model of a single leg
Each actuator has two cycloids which are 180* rotated relatively to each other. This is to minimize the vibrations coming from non-axial movements. Each cycloid has a main bearing in the center and seven small bearings around it. The outer pins are just pins – no bearings there.
The project looked fine on the computer, however, when I started to put it together I noticed a few problems:
-The cycloids must be perfectly manufactured. When too large they tend to latch, when too small the gearbox runs smoothly but has a lot of backlash. Building first prototypes I used to grind the cycloids with a file in order to make them fit the desired space. This was quite time-consuming, however it worked. The gearbox ran smoothly and it would show only about 1-2 degrees of backlash.
-Outer pin holder was very susceptible for any imperfections coming from the 3d printing process. A bit of extra material could twist the outer pins relatively to each other making the whole pattern irregular. Even when the cycloids were fine, this part would make the whole actuator latch at the same spot every rotation. -The last problem, which is still unresolved, is the connection between the thigh motor case and the rest of the leg. Currently, it relies mostly on one bearing and partially on the rods connecting the motor holder to the internal part of the thigh actuator. This can cause problems when the leg is being strained from the side.
Figure 2. Section view of the leg. Red circle shows one of the screws holding the bearing to the motor case, whereas blue shows the dangerous spot where the leg rests mostly on one bearing.
Thankfully my university owns a milling machine able to mill in aluminum. I decided to try milling a few cycloids and check how they do in this design. At first, the cycloids needed a few attempts in order to make them fit well. When adjusted the gearbox was operating without any latches but was a bit louder than the 3dprinted one.
Figure 3. milled cycloids
In the end, all the cycloids were milled form PA4 aluminum. Rings for outer pins, previously 3d-printed, were now also milled form a material called metaplex. It is similar to plexi, but is more shock resistant and do not break that easily.
...Read more »
Idea of control
Decided to build custom motor controller I was forced to learn about the technology used to control motors these days. My goal was to achieve high torque at very low rotational speeds. This assumption made me reject trapezoidal control as it is usually used to drive motors at high velocities, without any precision in positioning. Another considered type of control was sinusoidal – with appropriate PID control it was capable of driving the motor at really low speeds (limited by the resolution of the encoder). Reading about any other solutions I came across FOC ( Field Orientated Control). I’ve been reading about it for some time and eventually decided that it was the most sufficient way of driving the motor. The algorithm was dividing the current in two vectors – one responsible for field weakening (normal) and the other having direct impact on the torque (tangential). The goal was to bring the normal vector to 0 and control directly the torque using tangential component using PD control. In order to have feedback I had to read the phase currents with shunt resistors and then transform them into these two vectors.
Simulation and hardware
I started with computer simulation in order to see if I get it all right. When the virtual motor starter rotating I was able to start designing the hardware. The schematic and 2-layer circuit was developed in Eagle and then manufactured in China by PCBway.
Main features of the controller:
-DRV8323SRTAT MOSFET gate driver (SPI version)
-3x double N-channel
-12bit AS5145B encoder
-external connector for second encoder
I guess the board itself looks fine, it could be smaller (smaller footprints of the components) however I am satisfied with the result for now. That how it presents:
The board is mounted on top of the motor with two screws and the wires are soldered to the board directly as well as the output of the temperature sensor. Magnetic encoder is soldered on a little board to make space for the magnet glued on top of the rotor.
Testing and results
The controller worked fine when I first tested it, however when it came to current measurements they were quite “wavy”. The blue line on the screenshot from STMStudio is average of three phase currents, which should stay at fixed level :
It turned out I did not make separate Kelvin-connections for each shunt, and instead I just shorted the pins to the ground. Besides the measurement side of the controller was all a bit messed up and I had to fix it in order to make the return path as short as possible:
When corrected, the average wasn’t floating that much (grey line is the average) :
This modification turned out to lower the amplitude of the average current “waves” to an acceptable limit. The setup was ready for FOC algorithm with current feedback. The results were really promising. Below you can see two plots – first without current feedback (current in q axis vs torque) and the other with current feedback. As you can see the one with feedback is much more linear, thus it is possible to determine the torque constant.
In the end some photos of fully soldered motor controllers for two legs:
I think this is all for now, next I’ll post some details about mechanical aspects of the robot.