This project is my entry to the Arduino / Distrelec Automattion Contest of 2018. It is based on a skating robot I designed earlier this year and published as an idea. The "only" thing I needed to do was do develop a version which can be controlled via Blynk and then add more functions once there is a good user interface. Of course thing never are that easy and I write something about the project below.
The aim was to have more functions, like autonomous mode, but I needed to focus on haveing a working robot and things as neat as possible in the beginning of September to fit the contest dead line. I decided to instead add the feature with a servo and ultrasonic sensor and a simple user interface in my Blynk app. Autonomous moving is the next thing I will jump onto. I am anyway convinced that my robot in many ways is unique and maybe show one way of combining walking with wheeled propulsion.
The Concept BehindRobots can often fall into two categories, wheeled or walking. A wheeled robot is simple of design (basically a remote controlled car) and fast moving. Legged robots are more of an engineering challenge since they need complex programming in order to move their limbs, the challenge itself was one reason for me personally to develop my KITtyBot. The advantage with the legged type is the possibility to climb over obstacles and walk up and down stairs. This can be essential for rescue missions within buildings. But on flat ground the walking robot is slow compared to a wheeled. Then of course the concepts can be combined in many ways in order to have best from two worlds. A wheel robot with an advanced suspension can negotiate obstacles and eventually the "suspension" can be more like "legs" and allow some walking or climbing.
My project evaluates a robot with wheels that are passive, i.e they lack propulsion. There is instead a servo allowing for angling the wheels, basically like the front wheels on a car. Moving is done by skating (or maybe like paddling a canoe), i.e. using the possibility to angle the wheel and push forward using leg movements. This allows for a rather fast and energy efficient movement, at least compared to ordinary walking. The advantage over a conventional wheeled robot with "legged suspension" is that there is not need for motors driving the wheels. The robot can any time revert to walking.
Much of the design is similar to the robot KITtyBot I published here on the Project Hub. It uses the same Inverse Kinematics to move the feet and in case it does walking it uses the same walking gaits that I developed for KITtyBot. The new part is the "roller skates" added to the feet. The contact point of the wheel is located where the tip of the foot was on KITtyBot.
Building the RobotPrint the parts according to the supplied files. Take som time to look at the pictures and figure out how to assemble the parts before starting.
The hip joint should be assembled first. I have developed the design from KITtyBot by adding some more 3D printed parts. In doing so I also had to redesign the body, the new hip joint reauires a few mm more space. If you happen to have parts for a KITtyBot lying around or want ot convert one into this robot you can do that. The form factor will be the same once everything is assembled
Note that there are two versions called fl/rr (front left / rear right) and fr/rl (front right / rear left). Two sets of each kind are needed to make four hip joints. Make sure that you have the parts sorted. Apart from these four pins are needed and finally a new body. The legs and bumpers from the original KITtyBot are kept.
The pictures below show assembly of the joints. The step by step instruction in the figure below show how to do the fl/rr joint. The other joint should be straight forward once you have used up half of the parts. :)
Next is the foot joint. This also consist of two 3D printed parts and two servos each. There are four parts each called foot first and foot second. They are not separated into fr/rl and fl/rr version since will be altered by how the servos are mounted. The pictures below describe the mounting sequence.
After doing this the legs can be completed. Before proceeding it is good idea to make sure that all 12 servos are centered. The best way is to assemble the electronics, see below, connect all servos and the load the code. When the Arduino is started up all servos will center (command signal 90 degree).
The parts for the upper limb, thigh, and the part where the wheel is attached, called foot, have recesses that fit together with the servo horns that normally are delivered together with the servo. Glue horns into the recesses. Make sure to use a glue that works for joining the 3D printed material and the nylon plastic that the horn is made of. The glue gun I used worked fine, some better CA glues do also.
The complete leg assemblies should look like in the pictures below. First attach the two servo assemblies with the thigh part. The thigh is angled 30 degrees from vertical. This will be achieved when the centre of the wheel servo is in line with the centre of the lower hip, alpha, servo. Make it as close as possible and fine tune the centre positions in the code once everything is assembled (see below).
The foot part can then be assembled to it's servo. The wheel is made from the 3D printed rim with an o-ring as "tire". The wheel is mounted to the foot with M3 screws and nuts. Use two washers between the foot and wheel in order to make it roll as smoothly as possible.
The legs can then be assembled with the body. The bumpers should have servo horns glued into their recesses. The best way is to attach the servo drive into the bumpers' as close as possible to the desired angle, see below, and secure them with screws. A complete bumper with two legs can then be mounted onto the body and the bumper being secured with servo screws. Note: All screws supplied with servos will be needed to assemble servos onto the hip and foot joints. You probably have some extra mounting screws lying around, at least it is a good advice to have spare servos since they easily break.
The picture below show the assembled robot. The bread board for the electronic should fit on top of the robot. Attach the battery under the "belly" with velcro. It can be removed for charging, or replaced by a freshly charged, and also the centre of gravity can be adjusted by moving the battery around.
The goal with this project was to have autonomous navigation by help of an ultrasonic sensor, HC-SR04, mounted on a servo. Well, the hardware in terms of 3D printed parts are ready and the function itself has been tested together with the electronics. I simply add these items as they are at the time of contest dead line and you can choose to assemble them and play around a little, and maybe write code for autonomous navigation and publish. :)
The front bumper should be replaced by the US bumper and the sensor holder should be assembled on top of a 17th servo. The servo itself fit into the front bumper. When doing all this the centre of gravity moves forward. It is good idea to move the bread board on top of the robot to the rear.
Connecting the components is quite straight forward. Some things are however worth to mention. Before going any further I feel obliged to write something about LiPo batteries (a disclaimer I also wrote on my previous project KITtyBot).
I use a completely unprotected LiPo battery. This can be risky, the major hazards is to dis-charge it too fast or too deeply. The first hazard is avoided as long as it isn't accidentally short-circuited. A normal R/C battery has a discharge rate of 25 C which in this case allow for 12 A. The two UBECs will prevent it from being higher than 2 to 3 A each in any circumstances. The second hazard is prevented by the fact that the UBEC cannot supply voltage to the servos and the MKR if the battery voltage goes down to 6 V, which happens to be the limit for low voltage. To add surveillance a voltage indicator is fitted in the Blynk app. The KITyBot had an active voltage surveillance that put the robot to rest but it is not needed since the robot will stop working by itself before the voltage goes too deep.
And finally I must stress that the batteries should be charged with a purpose built charger and handled with usual care, never leave charging unattended. The battery should be detached from the robot (use velcro to mount it) and charged inside a fire proof bag or at least with a safe distance from flammable materials so a fire can be contained and not spread. Also store your batteries safely.
If you are not familiar with LiPo batteries consult a local R/C hobby store and buy batteries together with a suitable charger and possibly a fire proof bag/container for charging and storage. These items are often full of warning signs. Read them and use your own good judgement. :)
Connect the two UBECs to a battery lead. Also have two other wires feeding directly from the battery side. In my case these "two wires" was a scrapped servo cable with the signal (yellow or white) lead removed. It the fitted neatly onto a male-male header on the breadboard. It then became similar to the power out lead from the UBEC.
As shown on the schematics one power supply, UBEC 1, feeds the Servo Controller. The other, UBEC2, is connected to the "upper power rail" on the breadboard feeding the MKR. This rail can later be used to power more 5 V devices if needed, see below. The battery power (in my case the stripped servo cable) is connected to the lower power rail. From this the A1 pin is fed via two resistors to measure battery power. Via the two resistors the battery power is scaled down so 10.6 V converts to 3.3 V, giving a considerable margin to the maximum battery voltage of 8.4 V.
I had serious problem with jittering servos when I hooked up the electronics the first time. This is a known phenomenon and the servo controller is prepared for adding a capacitor to even out voltage oscillations. I saw the "rule of thumb" to use a capacity of about 100 uF per servo, in my case adding up to 1600 uF. I found a 2200 uF capacitor among my stuff and soldered onto the card and everything went fine. The supplied 3 A is a bit low for all this amount of servos (a worst-worst case scenario is about 8 to 10 A if all 16 servos stall at the same time), but with the capacitor added high peaks in power consumptions can be evened out.
In case you want to add the US sensor and servo there is another schematic showing what to add. Both the servo and the ultrasonic sensor works best at 5 V. Feed power from the 5V rail of the bread board. The components themselves work by getting 3.3 V signals from the MKR1000. But beware of one thing. The return signal from the US sensor, "echo", will be 5V. In order to protect the MKR1000 a voltage divider must be done with a 2.2 and 1.0 K resistor (or any other pair of resistors with the approximate 1 to 2 ratio in resistance).
The Blynk AppThe real novelty in this project was to use Blynk in order to have user interface on my iPhone and being able to control it via wifi. The usage of Blynk caused some rethinking of how to write the code. The basic rules for Blynk are:
- No delays
- Avoid having code in loop()
- Use timing (instead of doing the above two no-nos)
The reason for this (I think) is that blynk.run() needs to be called frequently. If it isn't everything goes bananas. The code for KITtyBot, which I planned to reuse and develop, definitely broke the second rule by having lengthy functions calls for several seconds. I could make it work by throwing in a blynk.run() command once in a while in the code, but when reading the forum it is really clear that the hard core experts says "use timing" followed by "it isn't har at all". I took this as a challenge and decided to rewrite in order to fit into the "Blynk way"
So the Arduino calls a function once every 100 ms. When doing it it either reads button status in order to receive new commands or continue with what it was doing 100 ms ago. A skate or walking gait consist of serveral sequenced movements, some of them can be executed within the 100 ms interval some of them needs to be divided into smaller parts, a synchronized move typically takes 500 ms. This, together with power supply problems took some considerable time to fix before the dead line of the contest.
The joystick controls the normal skating. The robots is quite controllable, it can go forward and reverse and do quite tight turns. I also added a switch to change mode to something called "dance" in which the joystick instead controls body movements in two directions. This was added more to show the ease with which a new function can be added by adding a Blynk widget and a few lines of code and using the function I developed for KITtyBot. Normal walking and turning is done the same way as on KITtyBot by pressing one of the four buttons and keeping them pressed for as long as you want it to move (the "only" thing I had to do was the Blynk rethinking).
A battery indicator is done by simply adding a vertical level connected to A1. The limits are 580 to 810. This, with 10.6 V being the maximum 1023 on the analog pin the level measures between 6.0 and 8.4 V (the limit which the battery should operate within). The widget updates once every second.
If the US sensor is added distance measurements are done by a Labeled Value widget. Also a slider is added to move the pan servo. The latter has the values limited to 20 to 160 in order to give commands within the servos 0 to 180 degree operating range (giving 20 degree of margin to the end points).
The image below show how I organized widgets on my iPhone. I have added comments on how to define each widget in the beginning of the Arduino code.
This picture from KITtyBot show how different geometric parameters are defined. The corresponding variables can be found in the Arduino code.
Before using the robots the center positions should be fine tuned. This is done by editing the array servodeg0 in the code:
const int servonum = 16; // The amount of servos
const float servodeg0[servonum] = {90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90};
The values are in order alfa, beta gamma and front/left, rear/left, front/right, rear/right. So beta on the front right is the eighth position in the array or servodeg0[7] (the numbering of the array starts with 0). The last four are the foot servos in order f/l, r/l, f/r r/r.
There is also an array called servodir that defines rotation direction of the servos.
const int servodir[servonum] = { +1, +1, -1, -1, -1, +1, -1, -1, -1, +1, +1, +1, -1, -1, -1, -1};
The servos I used move from from 0 to 180 degrees in counter-clockwise direction. I have read somewhere that there are servos going in the other direction. In such case the array servodir must have their signs changed all along.
Start up the Arduino and check the angles on all servos. Make measures and look that everything looks straight and symmetric.
Then skate around on the living room floor. :)
Comments