Hacking a robot

Previous post have summarized “THE HACKATHON” in TouK. Today we will present one of the projects in greater detail – “Lidar/ROS.org based robot”. Our team wanted to either transport sandwiches or monitor WiFi quality in the office. Not deciding on the final goal we immediately saw that mobile robot platform will be needed in both cases.

Analysis

Some of our coworkers own Xiaomi vacuum cleaners. Such robot can be managed from mobile app which displays accurate map of your premises and allows to select areas that need cleaning. Xiaomi robot looked promising but two problems arose. First, the price is significant. Second, the communication protocol is not open. There are libraries on GitHub which try to reverse engineer the details but quick analysis has shown that we may end up stuck on some irritating problem and fail to realise our goals.

Closer examination of Xiaomi robot has revealed the core piece that allows it to automatically navigate around the house. It is LIDAR – laser distance measurement device. Another brand of Roomba vacuum cleaners relies on camera-like sensor instead. As computer vision seemed more difficult to approach we have decided on using LIDAR to build two-dimensional map of robot’s surroundings and navigate around the office.

Hardware

LIDAR technology is not as cheap as simple ultrasonic distance sensors but we have found two promising solutions on the market: YDLIDAR and RPLIDAR. Both brands are lines of different products with increasing capabilities and prices but the basic ones were within our budget. Quick comparison has shown that parameters of respective lowest-end models are similiar so we decided to order YDLIDAR because it was the quickest to ship from Amazon to Poland.

One thing to note is that core LIDAR component can be acquired for even lower price but such device will have fixed line of sight. Our chosen model, just like the one built into Xiaomi, has full 360 degree rotating head. It makes 5 to 10 rotations per second scanning 5 thousand points in that time. The output data stream contains angle and distance for each measured point.

For our robot we needed a mobile base. Common choice is base with two motorized wheels plus one or two support wheels that freely rotate in all directions giving minimal friction. We discarded that option because such simple bases for amateur constructions have weak motors and we had quite a load to put on top. Professional bases with two powerful motors are expensive. In the end we bought four-wheeled base with independent low-grade DC motors driving each wheel. The wheels are not steerable – turning is done like in a tank. Our kit was also equipped with two motor encoders – devices that measure how many times wheel has rotated – we will try to use that knowledge later.

According to the manufacturer’s data our base can bear 800 grams of load. We have put there:

  • Raspberry Pi 3 B+, the most powerful model available
  • Arduino Uno
  • 4-channel motor shield for Arduino
  • YDLIDAR
  • LiPo battery pack
  • DC voltage regulators

We have decided that our robot should be fully autonomous so all the data processing will happen on-board using Raspberry Pi. It was connected via USB with Arduino which was used to control motors using standard Arduino-compatible controller. We knew that RPi has GPIO pins that can be used to control peripherals like Arduino would but we wanted to separate the concerns and use all the power of RPi for other responsibilities.

Ross robot
Ross robot

Software

We have assembled a mobile base with YDLIDAR mounted on top but YDLIDAR itself cannot build a complete map of our office and navigate around it. We needed algorithms that could interpret incoming data stream of distance measurements and convert it into usable map. We have found the ROS.org project. It is called Robot Operating System but instead of being full OS it is Linux-based framework – collection of tools and algorithms that makes programing robots easier. As hackathon was designed to deliver working products each team was given time to prepare before the main event. We have spent that time on learning ROS and gathering main components for our robot.

ROS is capable of handling LIDAR data, building a map and performing navigation of robot. If some feature is not available in ROS it can be added by coding of a “node” – separate program that communicates with another nodes using “topics” – ordered streams of events. Fortunately, all parts of our use case were already available as standard ROS nodes, topics and event types. YDLIDAR’s manufacturer provided custom ROS-compatible node which handles low-level interaction with device. There is also an Arduino relay library that makes it possible to write Arduino code that directly subscribes and publishes events to ROS topics.

Having written less than 100 lines of ROS nodes’ launch configuration in XML and less that 100 lines of Arduino code, we were able to remote control our robot and see the map on screen. We have used separate notebook which handled joystick controller and displayed a map. The notebook was configured as ROS slave connected over WiFi to ROS master running on RPi. Below we show how simple it was to setup USB joystick controller:


  

    
  

  

    
    
  

Unexpected problems and spontaneous solutions

During the hackathon days we have experienced some difficulties. As we were not able to test full robot assembly before the main event, some problems have surfaced very late in the process and dirty solutions must have been quickly hacked.

First problem: power source. During initial tests we used 24V DC power source connected to wall power. It had to be calibrated because internal protection cut off the power when current drawn by motors become too high. We also had 12V LiPo battery for final tests and show. Different input voltages were converted by on-board step-down regulators. One has provided 5V needed by RPi, Arduino and YDLIDAR. Second regulator fed 10V to the motors. During the tests it appeared that YDLIDAR cannot be powered from RPi’s USB port because its voltage was not stable enough. In the end we have connected YDLIDAR power input directly to 5V output from appropriate regulator.

Second problem: jerky movement. We thought (because ROS wiki suggested so) that it would be a good design to include PID controller driving the wheels. It is an algorithm that tries to maintain one value (in our case: measured actual speed of wheels) by varying another value that directly influences the first (in our case: power applied to motors). After some tests we have disabled PID controller because it requires fine tuning to behave correctly. As our rotational wheel encoders report only 10 ticks per revolution, the PID was confused by such low measurement resolution and tried to vary motor power too sharply rendering smooth movement impossible. We believe it can be tuned properly but during the hackathon we have setup joystick to directly control motors’ power, and not robot’s target speed, making human operator responsible for adjustments.

Third problem: faulty encoders. Our will to have wheel encoders originated not from possibility to enable PID controller, but from opportunity to increase mapping precision. Knowing how much robot has moved can help to better correlate data from multiple laser scans, producing more accurate map. Unfortunately, one of encoders appeared to work incorrectly, reporting too few ticks per revolution. Not having much time to investigate that we decided to disconnect encoders completely.

Making maps

At the beginning of second day we have already known main limitations of hardware and software and decided that we will use those parts that work predictably. We confirmed that PID controller was not neccessary for our purposes and mapping can be done using laser data only. We decided to enable simplest mapping algorith in ROS – a method called Hector SLAM. We could start first tests.

At first we mapped small room with two desks in it and a glass door. We have put additional objects in the middle to see how their presence would be handled. Everything worked smoothly using default parameters of Hector method. We also confirmed that it is easy to overlay map with additional data coming from sensors – in our case it was simple photoresistor measuring light intensity in the room.

Room
Room

Then we moved onto mapping bigger area – the hall between rooms. There is additional wall dividing it in the middle and a pillar. We added few other objects. During the tests robot was wired to the power source. We tested how to move our bodies around so to not interfere with the measurements. It appeared that after mapping initial fragment it is safe to walk around and Hector algorithm will ignore moving objects. Only after staying for too long in the same place our legs started to be included as part of the map.

Hall
Hall

Final test shows straight corridor. Its map is bended and we are not sure of the cause. It may be related to slow scan rate of YDLIDAR which accumulates error during robot’s movement.

Corridor
Corridor

Future work

Having learnt ROS before the hackathon and solved mostly hardware-related problems during the event, we have shown that map building is possible even with simple setup. We would like to expand the algorithmic part of the solution, enabling our robot to autonomously move in the office environment. Proper navigation components are already available in ROS.

Conclusions

ROS is a powerful tool that can be used both by amateurs and proffesionals. Its sophisticated architecture allows for complex definitions and management of industrial-grade robots, but can also fit in quick and dirty home projects. For us the biggest challenges lied in the hardware layer, but having electronic engineer on the team helped to connect all the parts together. All Ross team members are happy with results and wish to continue the project.

You May Also Like

Super Confitura Man

How Super Confitura Man came to be :)

Recently at TouK we had a one-day hackathon. There was no main theme for it, you just could post a project idea, gather people around it and hack on that idea for a whole day - drinks and pizza included.

My main idea was to create something that could be fun to build and be useful somehow to others. I’d figured out that since Confitura was just around a corner I could make a game, that would be playable at TouK’s booth at the conference venue. This idea seemed good enough to attract Rafał Nowak @RNowak3 and Marcin Jasion @marcinjasion - two TouK employees, that with me formed a team for the hackathon.

Confitura 01

The initial plan was to develop a simple mario-style game, with preceduraly generated levels, random collectible items and enemies. One of the ideas was to introduce Confitura Man as the main character, but due to time constraints, this fall through. We’ve decided to just choose a random available sprite for a character - hence the onion man :)

Confitura 02

How the game is played?

Since we wanted to have a scoreboard and have unique users, we’ve printed out QR codes. A person that would like to play the game could pick up a QR code, show it against a camera attached to the play booth. The start page scanned the QR code and launched the game with username read from paper code.

The rest of the game was playable with gamepad or keyboard.

Confitura game screen

Technicalities

Writing a game takes a lot of time and effort. We wanted to deliver, so we’ve decided to spend some time in the days before the hackathon just to bootstrap the technology stack of our enterprise.

We’ve decided that the game would be written in some Javascript based engine, with Google Chrome as a web platform. There are a lot of HTML5 game engines - list of html5 game engines and you could easily create a game with each and every of them. We’ve decided to use Phaser IO which handles a lot of difficult, game-related stuff on its own. So, we didn’t have to worry about physics, loading and storing assets, animations, object collisions, controls input/output. Go see for yourself, it is really nice and easy to use.

Scoreboard would be a rip-off from JIRA Survivor with stats being served from some web server app. To make things harder, the backend server was written in Clojure. With no experience in that language in the team, it was a bit risky, but the tasks of the server were trivial, so if all that clojure effort failed, it could be rewritten in something we know.

Statistics

During the whole Confitura day there were 69 unique players (69 QR codes were used), and 1237 games were played. The final score looked like this:

  1. Barister Lingerie 158 - 1450 points
  2. Boilerdang Custardbath 386 - 1060 points
  3. Benadryl Clarytin 306 - 870 points

And the obligatory scoreboard screenshot:

Confitura 03

Obstacles

The game, being created in just one day, had to have problems :) It wasn’t play tested enough, there were some rough edges. During the day we had to make a few fixes:

  • the server did not respect the highest score by specific user, it was just overwritting a user’s score with it’s latest one,
  • there was one feature not supported on keyboard, that was available on gamepad - turbo button
  • server was opening a database connection each time it got a request, so after around 5 minutes it would exhaust open file limit for MongoDB (backend database), this was easily fixed - thou the fix is a bit hackish :)

These were easily identified and fixed. Unfortunately there were issues that we were unable to fix while the event was on:

  • google chrome kept asking for the permission to use webcam - this was very annoying, and all the info found on the web did not work - StackOverflow thread
  • it was hard to start the game with QR code - either the codes were too small, or the lighting around that area was inappropriate - I think this issue could be fixed by printing larger codes,

Technology evaluation

All in all we were pretty happy with the chosen stack. Phaser was easy to use and left us with just the fun parts of the game creation process. Finding the right graphics with appropriate licensing was rather hard. We didn’t have enough time to polish all the visual aspects of the game before Confitura.

Writing a server in clojure was the most challenging part, with all the new syntax and new libraries. There were tasks, trivial in java/scala, but hard in Clojure - at least for a whimpy beginners :) Nevertheless Clojure seems like a really handy tool and I’d like to dive deeper into its ecosystem.

Source code

All of the sources for the game can be found here TouK/confitura-man.

The repository is split into two parts:

  • game - HTML5 game
  • server - clojure based backend server

To run the server you need to have a local MongoDB installation. Than in server’s directory run: $ lein ring server-headless This will start a server on http://localhost:3000

To run the game you need to install dependencies with bower and than run $ grunt from game’s directory.

To launch the QR reading part of the game, you enter http://localhost:9000/start.html. After scanning the code you’ll be redirected to http://localhost:9000/index.html - and the game starts.

Conclusion

Summing up, it was a great experience creating the game. It was fun to watch people playing the game. And even with all those glitches and stupid graphics, there were people vigorously playing it, which was awesome.

Thanks to Rafał and Michał for great coding experience, and thanks to all the players of our stupid little game. If you’d like to ask me about anything - feel free to contact me by mail or twitter @zygm0nt

Recently at TouK we had a one-day hackathon. There was no main theme for it, you just could post a project idea, gather people around it and hack on that idea for a whole day - drinks and pizza included.

My main idea was to create something that could be fun to build and be useful somehow to others. I’d figured out that since Confitura was just around a corner I could make a game, that would be playable at TouK’s booth at the conference venue. This idea seemed good enough to attract >Conclusion

Wicket form submit not safe for redirecting to intercept page

The problem When you have a form, that anybody can see, but only logged on users can POST, you may want to redirect the user to the login page, and back to the form after login Using wicket 1.3/1.4, if you do that using redirectToInterceptPage(loginP...The problem When you have a form, that anybody can see, but only logged on users can POST, you may want to redirect the user to the login page, and back to the form after login Using wicket 1.3/1.4, if you do that using redirectToInterceptPage(loginP...