HTML with Bootstrap Control Interface for ROSBot

While learning ROS, I was confident that it would be possible to replicate the kind of functionality I had built for SGVHAK rover. That is to say: putting up a HTML-based user interface for the user and talking to robot mechanical based on user input. Except that, in theory, the modular nature of ROS and its software support should mean it’ll take less time to build one. Or at least, it should be for someone who had already invested in the learning curve of ROS infrastructure.

At the time I didn’t know how long it would take to ramp up on ROS. I’m also a believer that it is educational to do something the hard way once to learn the ropes. So SGVHAK Rover received a pretty simple robot control built from minimal use of frameworks. Now that I’m ramping up on ROS, I’m debating whether it’s worthwhile to duplicate the functionality for self-education’s sake or if I want to go straight to something more functional than a remote control car.

This week I have confirmation a ROS web interface pretty simple to do: this recent post on Medium described one way of creating a web-based interface for a ROS robot. The web UI framework used in this tutorial is Bootstrap, and the sample robot is ROSBot. The choice of robot is no surprise since the Medium post was written by CEO of Husarion, maker of the robot. At MSRP of $1,299 it is quite a bit out of my budget for my own ROS experimentation at least for now. Still, the information on Medium may be useful if I tackle this project myself for a different robot, possibly SGVHAK rover or Sawppy.

Processed by: Helicon Filter;

 

JPL Open Source Rover is Officially Official

OSR RocksBack in January of this year I joined a team of pre-release beta testers for a project out of nearby Jet Propulsion Laboratory (JPL). While not exactly a state secret, we were asked not to overtly broadcast or advertise the project until after JPL’s own publicity office started doing so. This publicity release happened two days ago so the JPL Open Source Rover is now officially public.

Our team members drew from SGVHAK, so we’ve been calling our rover SGVHAK rover instead of JPL open source rover. Past blog entries talking about SGVHAK’s customization were described as done in contrast to a vague undefined “baseline rover.” I’ve gone back and edited those references (well, at least the ones I could find) to point to JPL’s rover web site. Which had gone live a few weeks ago but that was a “soft opening” until JPL’s publicity office made everything officially public.

After SGVHAK team completed the rover beta build in March, I went off on my own to build Sawppy the Rover as a much more affordable alternative to a rover model. To hit that $500 price point, I had described the changes and trade-offs against SGVHAK rover but it was really against JPL’s open source rover. I’ve fixed up these old blog posts minimally – the references are now correct though some of the sentence structures got a little awkward.

As part of JPL’s open source rover project, they had established a public web forum where people can post information about their builds. To share our story I’ve gone ahead and created a forum thread for SGVHAK rover, and a separate one for Sawppy.

I look forward to seeing what other people will build.

Embedding an Instagram Post with BBCode Without Plugin

Embedding an Instagram post is trivial on a WordPress blog like this one: copy the full Instagram URL (like https://www.instagram.com/p/BfryG0VnUmF/) and paste it into the visual editor window. Behind the scenes, that URL is parsed to create an embed as shown here.

There are similar plugins to add an tag to a BBCode-based web forum. But what if a forum does not have such direct support installed? This was the case for the web forum set up as community driven support for JPL’s Open Source Rover.

On every Instagram post, there’s an “Embed” option that will bring up a chunk of HTML (which links to some JavaScript) to create an embed. However, a BBCode based web forum does not allow embedding arbitrary HTML like that.

Time to read the manual which in this case is Instagram’s developer resources page about embedding. They prefer that people use the fancy methods like that chunk of HTML we can’t use. But way down towards the bottom, they do describe how to use the /media/ endpoint to pull down just an image file with no active components.

Instagram Rover L

This is simple enough to use within the BBCode [IMG] tag. Then we can surround that image tag with a [URL] tag to turn it into a link to the Instagram post.

[URL=https://www.instagram.com/p/BfryG0VnUmF/][IMG]https://instagram.com/p/BfryG0VnUmF/media/?size=m[/IMG][/URL]

It’s not as fancy as the full embed code, but it does get the basic point across and provides an easy way to access the original Instagram post. Good enough for a SGVHAK Rover post on the JPL OSR web forum.

Rovers Gonna Rove at SGVLUG/SGVHAK BBQ

The annual summer BBQ for San Gabriel Valley Linux User’s Group (SGVLUG + offshoot subgroups like SGVHAK) was this past weekend, so obviously a few projects from the group made a showing too. This included our SGVHAK rover and my own follow-up Sawppy the Rover.

Sawppy joined the socializing first, hanging out next to some of the seats attracting attention from members who haven’t seen the motorized rover model before. (And some who have but just wanted another look.)

SGVLUG BBQ 1

Later in the evening, SGVHAK rover joined on the party. The rovers would occasionally run around sometimes at the same time and sometimes into each other. They sort of got into the way of people at times, getting underfoot like a big cat might. Fortunately nobody tripped and fell over a rover.

SGVLUG BBQ 2

This was Sawppy’s first public outing since conversion to PETG, a conversion motivated by earlier PLA parts that deformed under heat. This weekend turned out to be a great test since the entire region is in the middle of a record-breaking heat wave. And this time, Sawppy did not melt under the scorching sun.

Sawppy also got a few different pilots, as anyone who expressed interest was offered a chance to take the helm. Partially to share the toy, but also to get some time seeing Sawppy driven by people who don’t drive the same way I do. The intent was to probe for unknown areas of weakness – after all, this type of activity is how we exposed the weakness in SGVHAK rover’s original steering mechanism.

Fortunately no such flaws were found today. Sawppy survived the evening driving by multiple people (and running over things, and running into things) without any apparent damage. This is a very good endorsement of Sawppy’s design maturity.

The Curse of the Right-Front Rover Wheel

During JPL’s IT Expo, Sawppy was on display and roaming around. Partway during the day, when setting up for a photo shoot, a shaft coupler tore out of Sawppy’s right-front steering servo. This was embarrassing and Sawppy limped along with some field repairs until the end of the day when we could analyze its failure and devise a path forward for all of Sawppy’s servos, not just the front-right wheel steering that failed.

On that day, the baseline JPL Open Source Rover was on display but was not driving because one of the steering couplers had failed on an earlier JPL outreach event and has yet to be repaired. Which wheel failed? The right-front wheel.

Even earlier – when the SGVHAK rover was just about to make its debut at SCaLE, a test drive session damaged the gearbox in one of the steering mechanisms. This required a short-term servo hack to get the rover back up and running in time for SCaLE. Which wheel was damaged and needed the hack? The right-front wheel.

Rover Servo Steering Hack

Spirit, one of the actual rovers on Mars, has a recurring mechanical issue with one of its wheels. Which wheel was it? The right-front wheel.

Four rovers, same problematic wheel.

There are likely some perfectly logical explanations for why this might happen, but to the irrational human mind, such stories are where superstitions are born.

Sawppy and SGVHAK Rovers at SGVLUG May 2018 Meet

SGVLUG201805

Yesterday was the monthly meeting of San Gabriel Valley Linux Users Group (SGVLUG) for May 2018. SGVHAK, the maker hacker group who built a rover, is a subset of SGVLUG and we got to present our project to the wider community.

The night’s presentation started with Eric Junkins of JPL talking about how JPL’s Open Source Rover came about. Several groups were invited to beta test the build instructions before public release and that was the stage where SGVHAK got involved. SGVHAK made a few changes to the baseline design for our own take on the project, exactly as the nature of open source release intended.

Towards the end Sawppy the Rover got a few minutes in the spotlight as a spin-off rover that was inspired by JPL’s Open Source Rover project. I got to talk about how it came out of an offhand comment by Eric and eventually I delivered a basic chassis that met his challenge of a $500 price point. It is not as fast, nor as powerful, nor as flexible as the JPL open source rover design. These were all trade-offs made in the name of hitting that price point.

After the presentation both rovers ventured out to the parking lot behind our meeting location (Du-Par’s Pasadena) and ran around for a while, attracting attention from passers-by along the way. The rovers may have managed to recruit a few new members to SGVLUG. We’ll see!

SGVHAK Rover Interface Avoids Confirmation Dialog

Shutdown Reboot

Our SGVHAK Rover’s brain prefers to be shut down gracefully rather than having its power removed at an arbitrary time. If power cuts out in the middle of a system write operation, it risks corrupting our system storage drive. While our control software is written to be fairly platform-agnostic, we’re primarily running it on Raspberry Pi which lacks a hardware shutdown button. So we need to create an UI to initiate a system shutdown via software.

The easiest thing to do would be to add a “Shutdown” button. And since it is a rather drastic event, have a “Are you sure?” confirmation dialog. This historically common pattern is falling out of favor with user interface designers. Computer users today are constantly inundated with confirmation dialog making them less effective. If our user has built up a habit of dismissing confirmation dialog without thinking, a confirmation dialog is no confirmation at all.

So how do we enforce confirmation of action without resorting to the overplayed confirmation dialog? We have to design our UI to prevent an accidental shutdown from a wayward finger press. To accomplish this goal, our shutdown procedure is designed so user must make a deliberate series of actions, none of which is “Yes/No’ on an ineffectual dialog box.

First – our user must enter a “System Power” menu. If they entered by mistake, any of the three active buttons will take then back to main menu. There’s no way to accidentally shutdown with a single mistaken tap.

Second – they must select “Shutdown” or “Reboot”, forcing a deliberate choice to be made before our UI activates “OK” button. If an incorrect selection is made, it can be corrected without accidentally triggering the action because both options are on the far left of the screen and “OK” is on the far right. Bottom line: Even with two accidental presses, our system will not shut down or reboot.

Third – With the “OK” button now activate after two deliberate actions, the user can tap it to begin the shutdown (or reboot) process.

SGVHAK Rover Steering Trim Adjustment

One of the changes we made to our SGVHAK Rover relative to the baseline design was a decision to omit absolute encoders for our corner steering motors. The baseline design used absolute encoders so it knows every wheel’s steering angle upon system startup, but we decided to sacrifice that ability in exchange for cost savings (~$50/ea * 4 corners = ~$200.) Since there is no free lunch, this decision also means we have additional work to do upon our system startup.

Our control software launches with the assumption that all steerable wheels are pointed straight front-back, which is of course not always true. We could manually push the wheels to straight front-back orientation before turning on power, but that’s not great for the gearbox. Also, the shaft coupler used to connect our motor gearbox to our steering mechanism is liable to slip. (This is considered a bug even though it has a potential feature: in theory sharp jolts to the system would slip the coupler instead of breaking something else in the system. In practice, we found that it didn’t slip enough to avoid breaking a gearbox.)

Given both of these scenarios, we need a software-based solution to adjust steering trim on the fly. Once our RoboClaw motor controller is told where zero degree position is, it is quite capable of holding a commanded angle until the coupler slips or the system reboots, whichever comes first.

Steering Trim

Steering trim adjustment took the form of a multi-stage HTML form designed for our specific workflow. First our user chooses a wheel to work with, and they are directed to do so because every other UI element on the page is inactive until one wheel is chosen.

Once a wheel is chosen, the remaining UI activates and wheel selection UI deactivates to guarantee we’re working on a single wheel at a time. In this stage, steering angle can be adjusted in 1- and 5-degree increments. When we’re satisfied our wheel has been returned to zero degrees deflection, we can select “Accept Current Angle as New Zero” to commit. We also have the option to abort adjustment and retain previous zero position. Either way, wheel selection activates to allow user to select another wheel, and the rest of the page deactivates until a wheel is chosen.

We have no scenarios where multiple steering motors need to be trimmed at the same time, so this user experience specifically focus on one wheel at a time makes the process straightforward. It also becomes impossible to make mistakes caused by user thinking they’re adjusting wheel when they’re actually adjusting another, which is a good thing for positive user experience.

SGVHAK Rover Control With Cartesian Coordinates

Having learned some valuable lessons from trying to drive our SGVHAK rover using an interface based on polar coordinates, we returned to the drawing board to create an alternative. Thankfully, the abstracted command structure meant we could experiment with front-end user interface without any changes to the back-end rover calculations.

Our first-hand experience taught us polar coordinate math are more trouble than it was worth, so our next attempt will stay in the Cartesian coordinate space. Furthermore, we’ll rearrange the layout so a position going full speed ahead would never be adjacent to a position going full speed reverse. (This was the case for polar coordinate system when doing full deflection turns.) Third, we’ll have to make sure low speed maneuvering has just as much room to fine-tune its angle as going high speed. And lastly, when someone releases their finger out of caution, we need to stop the rover but we don’t need to reset steering angles.

It turned out to be very easy to satisfy all of the above desires: map X-axis left-right dimension to steering angle, and Y-axis up-down dimension to speed.

Cartesian Pad

Full speed ahead is now along the top edge of the blue rectangle, which is far from the bottom edge representing full speed reverse. There is no longer any risk of suddenly jerking between them.

At any given speed, we now have the full width for designating steering angle, we are no longer frustrated by a tiny range of adjustments when moving slow speed versus high.

And finally, when the user releases their finger, the dot will snap to vertical center (stop moving) but will remain at its most recent horizontal position, preserving the steering angle most recently used by our rover driver. This makes fine position adjustments much easier by allowing slow incremental inching forward/reverse movements.

Most users who tried both UI design prefer the Cartesian coordinate system. It was used for most of our driving at SCaLE 16X.

SGVHAK Rover Control With Polar Coordinates

Once an abstraction layer was defined for communication between user interface and rover chassis calculations, I could start trying out various ideas for building a rover driving UI. The baseline rover UI presents two touchscreen controls mimicking joysticks on a traditional remote control vehicle: one moves up/down for controlling forward/back movement, and the other moves left/right for controlling steering. Driving the baseline rover using its UI is a two-thumb affair.

That is a perfectly valid and functional UI, but my ambitions grew beyond copying it. I wanted to explore ideas around single-finger operation. This decision held firm even after the person who created the UI for baseline rover warned us that it could be tricky to implement – single-point operation was already tried before going with the two-thumb approach. I may yet bow to their wisdom, but I wanted to give it a shot first!

Polar Pad

The first implementation of a one-finger driving control is based around polar coordinates. It seemed like an obvious match to rover mechanics: polar coordinates on a two-dimensional plane is an angle and a distance, which maps directly to rover control’s angle and velocity. The user puts their finger down on the red central control dot, and they can drag it around inside the blue circle to drive the rover. Move the dot up to drive forward, rotate the dot left to steer left, and so forth.

As I got into it, though, problems started to mount.

The first and most obvious problem is that our underlying infrastructure – HTML, <canvas> tag, and JavaScript input events – use cartesian coordinates. In order to implement polar coordinate control we need trigonometry math to convert between the two systems. Errors creep in as we perform multiple operations and conversions between coordinate spaces.

The second problem was a consequence of mapping upper semicircle to forward velocity and lower semicircle to moving backwards. This became problematic when the user wishes to steer at maximum angle.  Turning far left means moving straight left, but at that point small movements can flip between upper and lower semicircle, causing the rover to jerk suddenly between forward and backward movement.

To mitigate this, a band of dead space between the semicircles was introduced. The user is no longer able to use the full 180 degrees of a semicircle for movement, they are restricted to the middle 140 degrees with the far left 20 and far right 20 degrees blocked off. This was effective to prevent sudden transitions between full speed forward/backwards motion but it wasted screen real estate.

The third problem of polar coordinates was exposed when trying to maneuver the rover at low-speed around obstacles. When our finger is near the center of the circle, small left-right movement translates into large changes in steering angle. It was more difficult than it should be to make small steering changes at low speed.

The last problem is makes the above problem worse. When somebody runs into a problem, their first instinct is to lift their finger off the touchscreen. In order to retreat to a known safe condition, our control dot pops back to the center position representing wheels stopped and all steerable wheels pointing straight front-back. This is fine, but when people are frustrated by problem #3 of low-speed maneuverability, this behavior snapping to straight front-back erases whatever angle they were previously driving at, making low-speed maneuvers even more frustrating.

And what happens when a rover driver is trying to perform delicate maneuvers but find themselves fighting a bad UI that gets in the way and cause frustration? The rover ends up running into things and risk breaking gearboxes.

Now we have experimental evidence polar coordinate driving doesn’t work as originally thought, let’s take that lesson and create a new UI.

 

SGVHAK Rover Control Abstraction

Once we were confident our SGVHAK rover chassis control code looked pretty good, we were willing to trust that it could drive a rover without sending conflicting commands that make our rover try to twist itself into a pretzel. Now our focus turns to creating an interface for user control input.

A quick rough draft had been in place to help test rover chassis Ackermann math, letting a rover driver send a steering angle and travel speed to rover’s control code. But it was very tied to the current rover implementation: angle range was limited to angle range of what we have today, and speed was specified in raw quadrature pulses per second (QPPS) that we send straight down to RoboClaw motion controller‘s API.

Since we have ambitions for future rover variants, this direct dependency is not good. Future rovers may have a wider (or narrower) range of valid steering angles. They may also use something other than RoboClaw motor controllers. The answer is a typical software solution: abstraction!

This required changing the interface between our HTML UI front-end and the Flask-based Python code running on the rover. Instead of a fixed number angle or a fixed number of encoder pulses, user now send driving commands in terms of two percentages ranging from negative 100% to positive 100%.

For steering, -100% tells a rover to steer as far left as it could go, 0% is straight forward/back travel, and 100% is to steer as far right as it could go.

For velocity, -100% is travelling backwards as fast as it could, 0% is stop, and 100% is damn the torpedoes, full speed ahead.

Now when we adapt the code for future rover variants, we could focus on rover-side configuration and remain confident user-side HTML interface will automatically adapt to whatever capabilities are present on a particular rover variant.

This also allows us to experiment with user-side HTML without worrying about having to make matching changes in rover-side Python code. We can try different control schemes, as long as it ends up sending a velocity and steering angle percentage to the rover.

The first and crudest implementation of this concept is shown here: two HTML slider objects that move from -100% to 100%. The user can move the slider and tap “Send command” to rover. As the most basic HTML implementation possible, this is a useful test tool to isolate whether a particular control problem is in HTML front-end or in Python back-end, but it is obviously not a great driving interface.

That’s coming up next.

Velocity Angle

Visualizing SGVHAK Rover Chassis Calculations

When we were putting together code to calculate Ackermann steering angles for SGVHAK rover‘s wheels, initial testing was done via Python command line using some fixed test values to match against results pre-calculated by hand. Once we built some confidence our math was on the right track, it was time to start testing against more varied inputs.

There was just one minor problem – at this point in rover development, our software is a tiny bit ahead of the hardware which means we can’t test on hardware that hasn’t yet been assembled. Even if we could, it wouldn’t be a great idea to jump from a small fixed set of test values to actual hardware. As an intermediate step, we created a bit of code to visualize results of roverchass.py calculations: the “Chassis Configuration” screen will show what our control code thinks all six wheels should be doing. (This shows the intent, which is different from hardware telemetry of what’s actually happening.)

SGVHAK Rover Chassis Config

Each of the six wheels got its own blue box, laid out roughly analogous to their physical position on the rover chassis. Originally wheel steering & speed was displayed as text: number of degrees a wheel should be steered, and a second number reflecting the intended velocity for each wheel. This was accurate information but it took some effort to interpret. To make this information easier to understand, numerical text was changed to a visual representation.

By using HTML’s <canvas> element, we could draw some simple graphics. Each wheel is represented by a black rectangular outline. A wheel’s steering angle is now represented by tilting its rectangle to that angle. Inside a wheel’s rectangle is a green fill representing desired velocity. When a wheel is supposed to be stopped, there is no green fill and its black rectangle is empty. When a wheel is supposed to be rolling forward, green rectangle fills from the middle upwards. Faster velocity is represented by more green in the upper half. For a wheel that should be rolling backwards, green fills downwards instead.

This visualization of roverchassis.py calculation results were far easier for humans to understand. This made it very quick to validate that roverchassis is behaving roughly correctly. There’s a place for precise engineering calculations, but there’s also place for a quick glance to check “yeah, that looks about right.”

SGVHAK Rover Software: Chassis Calculations in Python

SGVHAK Rover Chassis ConfigOne of the biggest changes in our new rover controller code is the goal of managing all ten rover chassis motors together, starting to think of the rover as a single unit instead of ten individual things.

This logic is centered in roverchassis.py, which is be responsible for calculating Ackermann angles for all steerable wheels in the rover, as well as calculating the desired travel velocity for each wheel. In order to make this code as flexible as we can, we offload details of rover chassis into configuration files and make our Python math as generic as possible running calculations based on configuration file values. This meant we could support rovers with different geometries without editing source code. This feature began with a desire to have flexible wheelbase and track dimensions of our rover chassis, but eventually extended to supporting similar but different configurations such as two-wheel differential drive.

Another goal was to support different types of motors and motor controllers. We appreciated all the features in the RoboClaw motor controller we started with, but we also thought about trading off some of these features for lower cost. In preparation for this flexibility, we kept roverchassis.py focused on general Ackermann-related math and kept motor-specific code in a separate class. In the first draft, this meant pulling all RoboClaw related code into roboclaw_wrapper.py which translates general concepts from roverchassis.py into specific commands in Ion Motion Control’s public domain API roboclaw.py. Later on we validated this flexibility by steering a single wheel with a RC servo followed by adding support for LewanSoul serial bus servos.

This was all possible using a flexible syntax in config_roverchassis.json that allows us to adjust wheel dimensions as well as switch out individual wheel travel or steering motors for different motor controllers.

 

 

A Fresh Start for SGVHAK Rover UI

SGVHAK Rover Chassis ConfigWhen our SGVHAK rover project started moving beyond individual units of our custom wheel gearbox design and towards a multiple wheel chassis, it was happening on both the hardware and software fronts. Our Flask-based control UI has worked well up to this point, allowing us to tune RoboClaw motor controller parameters to suit our wheel design. Building this first draft UI taught us a lot, and as we learned we also realized how it reflected our ignorance at the beginning of this project.

And so we bid goodbye to our first draft rover UI RogerPiBot to start a new project SGVHAK_Rover. This way we retain all the testing & tuning capabilities of the existing software, leaving that as-is. Freeing us to create a new user experience.

The major changes are:

  1. Simple touch-friendly controls instead of HTML forms with a lot of fields. The form was a very powerful tool for tuning parameters from a desktop workstation, but we’re getting out of the engineering test phase. All interfaces will now be tailored towards operation from a small touchscreen.
  2. Rover as a unit instead of wheel as a unit. We need to start treating all six travel motors and four steering motors aboard our chassis as a single unit, as the user expects the software to do. Target audience for this software will not be interested in poke and prod at motors individually.
  3. Configuration files instead of source code edits. The new software is built on the assumption that will be people who want to use it but is not familiar with Python or code in particular. Part of this meant configuration information will now be stored in human-readable JSON files at the root directory instead of asking people to go in and edit Python source code.

There were various other changes big and small. One of the larger changes was separate from the rover itself: we chose to switch away from using Bootstrap purely for the sake of HTML creation exercise. This time around we’re using a different library called Materialize to help create our responsive UI.

Unfriendly UI For Two Wheel Test Chassis

Our first attempt at rover software was a wonderfully informative hands-on adventure on creating a path from a cell phone’s web browser HTML all the way to serial bus commands sent to a RoboClaw motor controller. Fortunately or unfortunately, these lessons also put a finite lifespan to the software as we start to discover basic mistakes that we didn’t know we were making until we got a little smarter.

Before we leave the first draft behind, however, it had one final role to play. This point in software development timeline coincided with our rover wheel development’s completion. The actual six-wheeled rover chassis is still in the future, but our wheel development is mature enough for us to build a test chassis. Two wheel units were assembled and integrated into a bare-bones test chassis.

This chassis needed a brain and a controller.

To enable motor control via differential drive, we hacked together a minimal user interface for sending commands to our test chassis. Not much effort was spent on user-friendliness and its layout is very much an engineering number cruncher’s idea of an interface. (Also referred to as “bad UI.”) It was just enough to let us move the robot around and uncover some finishing issues in the wheel design, but not much more than that.

The robot moving under its own power attracted attention from other people in the work space. Naturally some asked if they could try driving the robot but one look at the interface and the response was “Um… maybe I’ll wait for a later version” and the phone was handed back.

No offense taken, it’s another vote in favor of moving on. We’ll close out the “RogerPiBot” project at this point and start a new rover control project incorporating all the lessons we’ve learned.

Raw Differential Drive

Basic Motor Test for SGVHAK Rover

Our first opportunity to deploy the new Bootstrap-based touch-friendly HTML UI was a basic but critical motor test. A RoboClaw motor controller utilizes encoder feedback to know what the motor is doing. Based on this feedback, logic within the controller adjusts its electrical output to deliver either a commanded velocity or a commanded position. For any of that to work, an encoder must be installed properly. Our rover’s travelling wheel motors incorporated a pair of LED+photo diode units as optical quadrature encoders. Since we have a pair of sensors, there are two possible ways to wire them to RoboClaw input: one of which is correct and other is backwards.

To verify wiring, we need a basic motor test that will instruct RoboClaw to drive its motor at some power level, which is something it can do without encoder input. Then the test will query for encoder count and verify positive motor motion increments encoder count. If positive motion decrements encoder count, we’ll need to swap some wires.

Which wires need swapping? That depends on which way our motor is turning. We want positive motor rotation to correspond to forward rover motion, which means the left and right sides of the rover will be wired in mirror image. For rover’s right side wheels, positive motion will be clockwise (when viewed from rover’s right) and rover left wheels will be counter-clockwise. This desire to see the wheel motion in context of rover chassis is why we wanted this motor test to be usable on board the rover itself via the Raspberry Pi touchscreen.

If positive motor motion is rotating in the direction we want, and we need to swap wires, then we swap the encoder wires to maintain motor direction. If we need to swap wires and our motor is spinning in the wrong direction, we leave the encoder wires alone and swap our motor control wires instead. If the direction is wrong, and encoder is in sync, we’ll need to swap both sets of wires.

Basic Motor Test

HTML UI work described in this post began with this commit visible on Github.

RoboClaw HTML UI Work Assisted By API Stub

It was great when RoboClaw control UI project picked up help from somebody who knew what they were doing with web design. But it exposed a problem: the code is dependent on an actual RoboClaw motor controller connected to the machine. This was fine when development work focused on how to talk to the controller and hear what it has to say in return. But now that we have a parallel track working on improving the UI appearance, the RoboClaw dependency is unnecessary.

import roboclaw_stubTo remove this dependency, we introduced a RoboClaw API stub which could stand in for a physical RoboClaw when iterating through UI work. To do this in languages like C++, we would have to declare implementation of an interface and write a body. This makes sense when we expect all implementations of an interface to have roughly equivalent levels of functionality. For a test stub like this, though, that is not true. We only needed the small subset necessary to allow development of the specific relevant UI component. In languages like C++ this means most of the interface implementation would be tedious fillers that do nothing but raise a “Not Implemented” error.

Fortunately we are working in Python, which does not have such rigorous enforcement of interface implementations. We could implement just the methods we actually need to unblock UI development, and stop. There’s no need to recreate everything and we could leave out all superfluous “Not Implemented” declarations.

This is one arena where “duck typing” works in our favor, letting us get away with skipping all formalities of statically typed languages. There are downsides to dynamic binding but today it is a win.

Make RoboClaw HTML Control UI Scale Across Different Screen Types with Bootstrap

The basic HTML UI we were using to learn how to work with a RoboClaw motion controller was bare-bones web 1.0 in style. This worked very well when it only had to let us experiment to understand the controller while it’s sitting on a test stand next to the development workstation computer.

Once we got ready to move beyond tethered desktop computer scenarios, though, we had a problem. We had two touchscreen scenarios: one for UI directly on the robot via the Raspberry Pi Foundation touchscreen, the second scenario is remote control using a cell phone or tablet’s web browser.

Because the UI content was written in bare HTML, it does not scale to touchscreen devices the way we expect all modern web sites to do. In order to make this happen, we had to bring our HTML from the relative stone ages to conform to current practices.

Fortunately, this project received help from someone who has recently completed training on web design and development. [Amy] volunteered to jump in and make the controller HTML presentable and usable on touchscreen devices. Thanks to the open source nature of the web, most of the hard work has already been done by others and we just need to pull in one of the many freely available libraries to help build an UI that can respond to changes in the web browser environment.

For this experiment, [Amy] pulled in Bootstrap then began retrofitting the control test UI so Bootstrap can perform its magic across the different types of screens.

 

Link in Bootstrap

Refining Motor Parameters Applicable to SGVHAK Rover

Once we had a basic HTML UI for tuning RoboClaw PID parameters, we started exploring remaining surface area of RoboClaw API. In the arena of motor control, we have three categories of motion to choose from:

  1. PWM or duty cycle: This is the most basic type of control, where the motor is given a particular amount of power regardless of its load. If the motor is unloaded, it turns faster. If there is load, the power level does not change so motor slows down (or stalls). Since the quadrature encoder is not involved in this mode, it is particularly useful when diagnosing problems and we want to eliminate encoder error as a potential problem. There’s also no PID turning required for this mode to work, so it is also useful when trying to verify whether a problem is caused by bad PID gains or not.
  2. Velocity: In this mode, quadrature encoder activity matters. RoboClaw monitors encoder pulses and adjusts motor power to maintain the commanded velocity. If there is load of the motor, its slowdown will be apparent via encoder pulses and RoboClaw adds power to maintain commanded velocity. And conversely, when motor load is reduced and it starts speeding up, RoboClaw will see this in the encoder pulses and cut power to maintain commanded velocity. This is the mode we’ll use to control the wheel motors’ rolling travel. It requires a properly functioning encoder, at a high enough resolution, plus reasonably tuned velocity PID parameters.
  3. RoverTestConfig

    Position: In this mode, RoboClaw is told to move to a specific position and hold there. If external forces move the motor off its commanded position, RoboClaw will increase power to return to position and hold there. We will be using this mode to command motors in charge of wheel steering angle. In addition to the encoder requirement and velocity PID, there is a second set of position PID and both sets need to be tuned for a particular configuration.

Getting our bearings with RoboClaw motor control, we would first explore a tuning API from the command line then incorporate it into our HTML-based UI so we could rapidly iterate through parameter values.

The many iterations of this exploratory and tuning adventure (including all the mis-steps along the way) are publicly visible on Github.

Web-Based RoboClaw Control For Test and Configuration

The first step in the journey to a HTML-based rover UI is to prove we can write something in Flask to allow a web browser to send command to a RoboClaw motion controller. The next step is to build something useful. Early on in SGVHAK rover project, that meant a technical tool to configure and test motor control parameters.

The goal of this tool is to simplify tasks done earlier via typing RoboClaw API commands into the interactive Python shell. As part of proving the browser interface concept, we’ll also try to make the interface usable from a touchscreen device. More point-and-click, less typing on a keyboard. We’re not putting too much effort into making the user experience pretty and polished, though. This is an engineering tuning and testing tool, not an end-user tool.

The advantages of using a web framework immediately paid off in the ease of building sets of motor controls. It allowed rapidly iterating through ideas to find the feature set that would be useful and discarding features that are not. There’s little wasted effort as we’re not worried about making things look good and are OK with primitive web 1.0 forms.

One downside is not the fault of a web framework, it is more a consequence of trying to fit a square peg in a round hole. Web apps are fundamentally focused on supporting large numbers of users, and here we’re really only concerned about controlling a single resource: the RoboClaw. Flask is built around some patterns intended to help developers write code that scales to high number of users & sessions. But in the context of this single-user, single-session usage, such patterns sometimes got in the way.

Another downside is a web-based interface inherits all the problems of the web. Inputs sent by a client is inherently untrustworthy and must be properly validated before processing. The web framework can help handle some of that with automatic protection of cross-site scripting attacks, but the developer is ultimately responsible for sanitizing the input before processing. In the context of an engineering tool with short expected useful life, it’s a problem we can set aside for now.

RoverTestConfig

The proof of concept code discussed in this blog post is available on GitHub: testconfig.py under https://github.com/Roger-random/RogerPiBot