{"id":413469,"date":"2024-06-29T23:08:42","date_gmt":"2024-06-29T23:08:42","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=413469"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=413469","title":{"rendered":"<span>Robotic Floor Washer<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>When we think about robots, the first thing that comes to mind are robotic vacuum cleaners. The reason is simple: they are the most &#171;solid&#187; demonstration of success of &#171;consumer&#187; robotics. So making one sounds like a good idea&#8230; at first.<\/p>\n<p>But isn&#8217;t it a bit counter productive &#8212; to build something that popular, something we can buy in a store at a commodity (small) price? Should we build something similar, but NOT a vacuum cleaner? Something like&#8230; a floor washer, perhaps? Yes, a robotic floor washer.<\/p>\n<p>In this tutorial I am going to build a fully working prototype of a robotic floor washer. By &#171;fully working&#187; I mean that it is going to wash floor, instead of moving dirt around like most robotic &#171;moppers&#187; do. While by &#171;prototype&#187; I mean it is going to be the first step towards production-ready unit, but not a production-ready unit yet. Let me explain.<\/p>\n<p>First of all, it is not going to be THAT solid. You can grab a robotic vacuum cleaner that you got from the store by any part, including wheels and bumper and lift it. It will not fall apart. Ours probably will. The reason is, to make a device &#171;mechanically solid&#187; is a separate task, and if we focus on it, then &#171;robotic&#187; tasks will become more difficult to achieve. So we are going to do what engineers usually do: first  they build C3PO without the outside body, wires everywhere and so on. And only then they put a gold-covered outfit on it.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/931\/d06\/1f9\/931d061f928f6f56d3870f42908e3ba8.jpg\" width=\"350\" height=\"488\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/931\/d06\/1f9\/931d061f928f6f56d3870f42908e3ba8.jpg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/fc5\/474\/516\/fc54745168e4e05f5cc72917c1791665.jpg\" width=\"288\" height=\"600\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/fc5\/474\/516\/fc54745168e4e05f5cc72917c1791665.jpg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<p>Other than &#171;solidity&#187;, we are going to make some more simplifications, compared to a production ready unit. First, we&#8217;ll use Arduino. It is an insanely popular universal processor, but if you open a vacuum cleaner from the store, you&#8217;ll see a specialized processor instead. Obviously, it is cheaper to produce and to fix, but it is harder to design.<\/p>\n<p>Second, we are not going to pay any attention to layout of wires. This is acceptable for a simple prototype (ours is simple, by the way), but a hundred percent show stopper when it comes to production. But this is a tutorial, not a final spec.<\/p>\n<p>Finally (and it is closely related to our decision to not make the prototype &#171;solid&#187;) we are not going to make it compact. The reason is obvious: when you need access to something, you should get it in one step. Try getting into a vacuum cleaner you got from the store, and you will see what I mean.<\/p>\n<p>However, this all said, the prototype will do what it is supposed to do, and can be considered as, well, a prototype. The next step (one I am going to skip) would be building a production-ready unit based on it.<\/p>\n<\/p>\n<h2>Mechanical Part<\/h2>\n<p><strong>Base<\/strong><\/p>\n<p>Before we begin, we need to figure out what is it we are going to build. As you saw before (compare <a href=\"https:\/\/robotics.snowcron.com\/vc_platform_1\/vc_platform_1.htm\" rel=\"noopener noreferrer nofollow\">VC Prototype 1<\/a> and <a href=\"https:\/\/robotics.snowcron.com\/vc_platform\/vc_platform.htm\" rel=\"noopener noreferrer nofollow\">VC Prototype 2<\/a>), there are many ways of moving a mop around the room. As we want to build a programmable device and not a mechanical toy, we are going to choose a &#171;round design with a bumper&#187;.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/615\/d80\/c53\/615d80c533dff6a71f1b8796ccd53236.png\" width=\"200\" height=\"200\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/615\/d80\/c53\/615d80c533dff6a71f1b8796ccd53236.png\"\/><figcaption><\/figcaption><\/figure>\n<p>We are going to build a 360 mm diameter circular design.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/8f9\/591\/ea2\/8f9591ea2410c315fa558bdef4e965b3.png\" width=\"502\" height=\"397\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/8f9\/591\/ea2\/8f9591ea2410c315fa558bdef4e965b3.png\"\/><figcaption><\/figcaption><\/figure>\n<p>As I mentioned many times in my tutorials, you can use almost any materials and tools. However, if you are serious about robotics, you should consider buying (it is about $100) or building (<a href=\"https:\/\/reprap.snowcron.com\" rel=\"noopener noreferrer nofollow\">Reprap DIY<\/a>) a RepRap printer. By the way, building a 3d printer is not that hard and is definitely easier than building a robotic vacuum cleaner.<\/p>\n<p>So I am using a 3d printer. What does it mean for my design? <\/p>\n<p>The size. A reprap can print objects of the 200 x 200 x 300 mm, so to pring the base of our Floor Washer, we need to cut it in CAD designer program and then to glue it together (I do it by glueing plastic bande to the bottom of the connection line.<\/p>\n<p>As for the CAD software, I am going to use <a href=\"https:\/\/tinkercad.com\" rel=\"noopener noreferrer nofollow\">Tinkercad<\/a>, a simple and very nice online designer.<\/p>\n<p>So, here is the base for our robot, with technical holes and space for wheels and other peripherial staff:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/dcc\/8a9\/655\/dcc8a96552ff287f168c337c755b4497.png\" width=\"378\" height=\"417\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/dcc\/8a9\/655\/dcc8a96552ff287f168c337c755b4497.png\"\/><figcaption><\/figcaption><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/66b\/2f7\/8aa\/66b2f78aae89877a5abaddf595dc153c.jpg\" width=\"600\" height=\"398\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/66b\/2f7\/8aa\/66b2f78aae89877a5abaddf595dc153c.jpg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<p><strong>Wheels<\/strong><\/p>\n<p>Next, we want to attach wheels. We are going to use cheap motors from Ali store, you can, of course, replace them with whatever you can obtain from broken toys. The only requirement is voltage (we use 6V, but it is adjustable) and speed (we need our robot to be 2-3 times slower that a robotic VC would be).<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a1b\/43f\/764\/a1b43f7649df234217e485ec8a761657.png\" width=\"332\" height=\"479\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a1b\/43f\/764\/a1b43f7649df234217e485ec8a761657.png\"\/><figcaption><\/figcaption><\/figure>\n<p>3d printer allows you to print virtually anything, so our wheels have nice holes (that serve no purpose aside from being nice) and slots on the outer part.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d83\/47b\/611\/d8347b611a7be7b5d1f52d76baea0e91.png\" width=\"377\" height=\"382\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d83\/47b\/611\/d8347b611a7be7b5d1f52d76baea0e91.png\"\/><figcaption><\/figcaption><\/figure>\n<p>The reason we use those &#171;slots&#187; is friction. Plastic wheel slides on a dusty floor, and so does rubber, if it is covered with dust. So we need to increase adhesion somehow. A simple approach is to put soft regular objects on the wheel, in this particular case, I use fragments of the line I got from the jumping ropes:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/ce1\/629\/f6e\/ce1629f6ecd5ce451516e026d783dcf5.jpg\" width=\"600\" height=\"398\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ce1\/629\/f6e\/ce1629f6ecd5ce451516e026d783dcf5.jpg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/115\/05c\/768\/11505c76871debe514a2cdc04b43be7e.jpg\" width=\"600\" height=\"398\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/115\/05c\/768\/11505c76871debe514a2cdc04b43be7e.jpg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<p>Note the way we use the large gear to additionally reduce speed of the motor.<\/p>\n<p><strong>Wheel motors and gears<\/strong><\/p>\n<p>In our particular case, we use nuts hot-pressed (with soldering iron) into the gear to make sure axes are attacher properly and will not slide&#187;<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/eb3\/606\/4ab\/eb36064ab72868589c2ffb579daa279d.jpg\" width=\"600\" height=\"398\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/eb3\/606\/4ab\/eb36064ab72868589c2ffb579daa279d.jpg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<p>Now, the green box around gears should, in a production-ready design be solid. Here, however, it has holes, to make easier to see what is going on inside and to make it possible, if necessary, to reach inside with a pin set.<\/p>\n<p>Gears are being held using bearings, placed in the cylindrical holes in the gear box:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/944\/ad8\/53e\/944ad853ebfdd5e7189264199e07c266.png\" width=\"256\" height=\"176\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/944\/ad8\/53e\/944ad853ebfdd5e7189264199e07c266.png\"\/><figcaption><\/figcaption><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/3ad\/56a\/52e\/3ad56a52e39b7b2ebb9ce793bb63a034.png\" width=\"728\" height=\"568\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/3ad\/56a\/52e\/3ad56a52e39b7b2ebb9ce793bb63a034.png\"\/><figcaption><\/figcaption><\/figure>\n<p>The gear is too large to fit above the Floor Washer base, so we need to cut hole in it. Of course, we can not use it like that, the gear will be covered with dust, hairs and become stuck. So later we will print a cpecial box to cover the bottom of the gear:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/6c3\/83d\/eb0\/6c383deb05e5727b025604e03c8d196d.png\" width=\"326\" height=\"295\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/6c3\/83d\/eb0\/6c383deb05e5727b025604e03c8d196d.png\"\/><figcaption><\/figcaption><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/49d\/a32\/92b\/49da3292be5c98e04c62329f4c6f206c.jpg\" width=\"600\" height=\"398\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/49d\/a32\/92b\/49da3292be5c98e04c62329f4c6f206c.jpg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<p>Now, there was an intentional error in an image of motors above. We are going to use glue a lot here (while prodiction unit will use bolts), so if we put motors between motor holding box and gear holding box&#8230; We will not be able to remove it, without breaking the glue. So we turn the motor holder boxes around:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/aec\/4e4\/053\/aec4e405355a1c3929a7907270648ded.png\" width=\"364\" height=\"518\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/aec\/4e4\/053\/aec4e405355a1c3929a7907270648ded.png\"\/><figcaption><\/figcaption><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/3fc\/59e\/fad\/3fc59efadabec46c5da343ab260ad4fe.jpg\" width=\"600\" height=\"465\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/3fc\/59e\/fad\/3fc59efadabec46c5da343ab260ad4fe.jpg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<p><strong>Water basket<\/strong><\/p>\n<p>The next step is installing the box with water. I used one I got in a grocery store. The reason we put it in place now is that it is large, and all other objects should be placed around it, or at least with it in mind. On the picture you can see click-fit holders that keep the box in place, in an actual device I used glue (which is cheating).<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/02f\/630\/3e6\/02f6303e642d2fc173cb277953472e1d.png\" width=\"376\" height=\"490\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/02f\/630\/3e6\/02f6303e642d2fc173cb277953472e1d.png\"\/><figcaption><\/figcaption><\/figure>\n<p><strong>Side brushes<\/strong><\/p>\n<p>Next, we need side brushes. We use small motors with reductors from Ali, that are surprisingly good for this purpose:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/fd8\/53a\/38f\/fd853a38f38faea9c0f1e39c2cf15a00.png\" width=\"357\" height=\"464\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/fd8\/53a\/38f\/fd853a38f38faea9c0f1e39c2cf15a00.png\"\/><figcaption><\/figcaption><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/22a\/bfd\/7c2\/22abfd7c20708e8fec62d7c30d9827a1.png\" width=\"594\" height=\"242\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/22a\/bfd\/7c2\/22abfd7c20708e8fec62d7c30d9827a1.png\"\/><figcaption><\/figcaption><\/figure>\n<p>We also use ready side brushes (Ali again):<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c86\/02e\/471\/c8602e4710c9bf1beca3f6dd8bd8b417.png\" width=\"500\" height=\"252\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c86\/02e\/471\/c8602e4710c9bf1beca3f6dd8bd8b417.png\"\/><figcaption><\/figcaption><\/figure>\n<p>As you can see, we need a larger hole on the robot&#8217;s base:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d8a\/ed9\/89b\/d8aed989b0702f2df5960787071cf2d0.png\" width=\"544\" height=\"591\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d8a\/ed9\/89b\/d8aed989b0702f2df5960787071cf2d0.png\"\/><figcaption><\/figcaption><\/figure>\n<p>We need to lift the motor so that brush is half-immersed in the base:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/b2d\/bd2\/918\/b2dbd2918187a9eaf52bd3e344299caf.png\" width=\"397\" height=\"464\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b2d\/bd2\/918\/b2dbd2918187a9eaf52bd3e344299caf.png\"\/><figcaption><\/figcaption><\/figure>\n<p>Of course, in the production-ready design this &#171;box&#187; should be made smooth, following the shape of the top of a brush. This looks nicer, but doesn&#8217;t affect anything in terms of usability.<\/p>\n<p>Now, we are going to place a motor on top of that &#171;box&#187; and to cover it with a &#171;holder&#187;. That way motor can not move up or down, neither can it spin. We can attach brush to it by simply pushing from below:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/713\/de6\/3f1\/713de63f15e7f89147c783abd1becf9b.png\" width=\"160\" height=\"334\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/713\/de6\/3f1\/713de63f15e7f89147c783abd1becf9b.png\"\/><figcaption><\/figcaption><\/figure>\n<p>This is what side prushes look when they are in place with their motors:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/5a4\/7e7\/159\/5a47e7159f39e9a6bacc9d0e0a54444d.png\" width=\"357\" height=\"401\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/5a4\/7e7\/159\/5a47e7159f39e9a6bacc9d0e0a54444d.png\"\/><figcaption><\/figcaption><\/figure>\n<p><strong>Bumper<\/strong><\/p>\n<p>The next step is a bumper of course. As was mentioned before, 3d printer has size limitations, so we print parts and then glue them together:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/656\/6a7\/a6f\/6566a7a6f89fd292b8689633eb4392de.png\" width=\"437\" height=\"440\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/656\/6a7\/a6f\/6566a7a6f89fd292b8689633eb4392de.png\"\/><figcaption><\/figcaption><\/figure>\n<p>Note that in this design I added 3 slots for ultra sonic sensors. The way they are usually used in &#171;normal&#187; VC is, to detect a wall in advance, and to drop the speed, so instead of a loud collision we have a soft touch. However, to make washer to wipe the floor better, I had to reduce the speed about 3 times, so  sensors are not necessary. It moves slow enough already:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/43c\/ed2\/6b7\/43ced26b7df623ef474477f3cf5f889a.png\" width=\"427\" height=\"479\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/43c\/ed2\/6b7\/43ced26b7df623ef474477f3cf5f889a.png\"\/><figcaption><\/figcaption><\/figure>\n<p>Note the way shields of the bumper overlap to increase total rigidness of the structure:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/70b\/e3b\/a01\/70be3ba014b8005b0275cdf660ffca9a.png\" width=\"294\" height=\"299\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/70b\/e3b\/a01\/70be3ba014b8005b0275cdf660ffca9a.png\"\/><figcaption><\/figcaption><\/figure>\n<p>Last shields on the right and left sides have different shape: in theory, it should reduce incidents when the robot turns and left\/right end of a bumper hits the obstacle.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/178\/a0b\/411\/178a0b411dcd3d07181b0c5c700ceb1e.png\" width=\"384\" height=\"435\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/178\/a0b\/411\/178a0b411dcd3d07181b0c5c700ceb1e.png\"\/><figcaption><\/figcaption><\/figure>\n<p>In a production-ready unit this sort of incidents should be excluded by precise design:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/888\/91d\/b53\/88891db5384bf1718470f714fb919219.jpg\" width=\"600\" height=\"336\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/888\/91d\/b53\/88891db5384bf1718470f714fb919219.jpg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<p><strong>Bump sensors<\/strong><\/p>\n<p>Next, we need sensors that detect the fact that bumper was moved. Leaving design specifics aside, they are nothing but clickable buttons:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/bee\/6fc\/e6f\/bee6fce6f1d2e35b3edf2a8763a342a6.jpg\" width=\"500\" height=\"341\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/bee\/6fc\/e6f\/bee6fce6f1d2e35b3edf2a8763a342a6.jpg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<p>We are going to install 3 sensors: two on top of wheels at the sides of our robot and one in front.<\/p>\n<p>Side sensors have to be lifted up so that they are on top of the wheel:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/092\/e6e\/56a\/092e6e56ae78e52d27531ee02d891d16.png\" width=\"496\" height=\"474\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/092\/e6e\/56a\/092e6e56ae78e52d27531ee02d891d16.png\"\/><figcaption><\/figcaption><\/figure>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/200\/c99\/17b\/200c9917bd2fd48bf781c090bd8382d4.png\" width=\"394\" height=\"583\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/200\/c99\/17b\/200c9917bd2fd48bf781c090bd8382d4.png\"\/><figcaption><\/figcaption><\/figure>\n<p>When the corresponding side of the bumper hits the obstacle, it moves towards the sensor and presses it, as it is nothing but a pressable button:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a8b\/a94\/da6\/a8ba94da6df90c37d2ac162b89c198e4.png\" width=\"351\" height=\"499\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a8b\/a94\/da6\/a8ba94da6df90c37d2ac162b89c198e4.png\"\/><figcaption><\/figcaption><\/figure>\n<p>As for the front sensor, we lift it just slightly using U-shaped plastic holder. It is located at the center (or almost at the center) of a bumper. The following image shows the central sensor, to make it easier to read, I moved the bumper forward a bit.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/fd5\/db9\/1e0\/fd5db91e08f40b6b8db891a411a8047f.png\" width=\"491\" height=\"359\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/fd5\/db9\/1e0\/fd5db91e08f40b6b8db891a411a8047f.png\"\/><figcaption><\/figcaption><\/figure>\n<p>Note the &#171;almost&#187; above. It is a common situation in mechanical design, when we need to place more than one device at the center (corner, top etc) of our robot. In our case, the holder of a bumper should be at the center line, as well as the sensor: what should we do?<\/p>\n<p>Well, we should ask ourselves &#171;should it really be EXACTLY at the center line, and if the answer is &#171;no&#187;, we should move it few centimeters to the side.<\/p>\n<p>So, as we mentioned the bumper holders, let&#8217;s discuss them. Earlier, in <a href=\"https:\/\/robotics.snowcron.com\/vc_platform_1\/vc_platform_1.htm\" rel=\"noopener noreferrer nofollow\">VC Prototype 1<\/a> I &#171;invented&#187; a simple mechanical schematics, allowing the bumper to move as we need it to, and preventing it from swinging to the sides and doing other unwanted sort of things. That design was ok, but printing it (or making it by hand) was tricky and it didn&#8217;t look nice. So for this project I have &#171;invented&#187; another one, which is kind of nicer. Note the quotes around &#171;invented&#187;: I am pretty sure it have been invented many times before me; luckily, I am not using this design to actually produce robots. Otherwise, your patent lawyer should probably make sure it is financially safe.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/b42\/852\/4b7\/b428524b788328eec6df15d7ce905154.png\" width=\"298\" height=\"461\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b42\/852\/4b7\/b428524b788328eec6df15d7ce905154.png\"\/><figcaption><\/figcaption><\/figure>\n<p>As you can see, this simple device can extend\/collapse along horizontal axe, but is rigid enough to NOT bend up or down: just what we need from our bumper. Once again, we are going to hold bumper &#171;in the air&#187; using 3 devices like at the picture above (left, center and right ones).<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/674\/8e8\/cc2\/6748e8cc2d32e14a8e0fea05d70e2bff.png\" width=\"506\" height=\"570\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/674\/8e8\/cc2\/6748e8cc2d32e14a8e0fea05d70e2bff.png\"\/><figcaption><\/figcaption><\/figure>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/1f1\/2f5\/43e\/1f12f543e10fd5837899d7f92e9567b2.png\" width=\"355\" height=\"460\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/1f1\/2f5\/43e\/1f12f543e10fd5837899d7f92e9567b2.png\"\/><figcaption><\/figcaption><\/figure>\n<p>If you think about it, this design is insufficient. What if we move the bumper to the side, like at the image we presented earlier?<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/b30\/9b2\/2ab\/b309b22ab134b2095a704a3b7b27da24.jpg\" width=\"400\" height=\"420\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b30\/9b2\/2ab\/b309b22ab134b2095a704a3b7b27da24.jpg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<p>If the obstacle presses against the end (left or right) of a bumper and we only have holders presented on pictures above, it (the bumper) will slide around the body of a robot&#8230; which is not what we want.<\/p>\n<p>So we have to introduce an additional stopper, one preventing the bumper from going sideways:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d5d\/bcc\/792\/d5dbcc7925f7ccc5344720f3d97ea0af.png\" width=\"443\" height=\"515\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d5d\/bcc\/792\/d5dbcc7925f7ccc5344720f3d97ea0af.png\"\/><figcaption><\/figcaption><\/figure>\n<p>As you can see, it is a simple restriction we placed around the central bumper holder, nor our bumper can move ONLY as the VC bumper should.<\/p>\n<p><strong>Battery holder<\/strong><\/p>\n<p>The next thing is a battery holder. Here we have two choices: we can use NiMh accumulators, or we can use Lithium ones. As Lithium cas capacity that is about 3 times higher, the choice seems obvious, but&#8230; We are going to use NiMh. <\/p>\n<p>You see, this is a tutorial. And it can be read and implemented by beginners. While Lithium accumulators, when handled wrong, combust. It becomes even worse when you think about water we carry around: humid electronics burns even better. So we stick to a safer accumulators,  even though we&#8217;ll need more of them.<\/p>\n<p>Of course, nothing prevents you from using Lithium accumulators, at your own risk.<\/p>\n<p>Here is a battery compartment. I an going to hold there 8 holders obtained from Ali, with 4 accumulators each:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/eb6\/073\/96a\/eb607396aee78676d0591df5c6a6d0a3.png\" width=\"355\" height=\"376\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/eb6\/073\/96a\/eb607396aee78676d0591df5c6a6d0a3.png\"\/><figcaption><\/figcaption><\/figure>\n<p>When fully charged, his battery pack produces 19.2 V (16 batteries in a pack, 1.2 V each battery, 2 packs connected in parallel).<\/p>\n<p>Battery pack:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ec1\/4e7\/7eb\/ec14e77eb325036a0e18315a68223625.png\" width=\"244\" height=\"398\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ec1\/4e7\/7eb\/ec14e77eb325036a0e18315a68223625.png\"\/><figcaption><\/figcaption><\/figure>\n<p>Battery pack in place:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/16d\/e45\/f44\/16de45f44af62a3c5c45fb792dab579b.png\" width=\"363\" height=\"550\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/16d\/e45\/f44\/16de45f44af62a3c5c45fb792dab579b.png\"\/><figcaption><\/figcaption><\/figure>\n<p>Note one thing that probably is not obvious: all heavy objects, like battery pack and basket with water, are located in front of the wheels. See, our robot has 3 wheels, and if its back side was heavier, the front wheel would go up, and the robot would &#171;sit&#187;. Which is not what we need. So we make sure its weight is between wheels, not behind.<\/p>\n<p><strong>Power switch holder<\/strong><\/p>\n<p>Now we need to install a holder for the power switch. I use one of countless power switches you can get, so if yours is different, you will have to design something appropriate. What this holder does is keeping the switch raised, so that wires that go to it can be hidden below:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e27\/de0\/bba\/e27de0bba208a0755194e30f322cb517.png\" width=\"147\" height=\"193\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e27\/de0\/bba\/e27de0bba208a0755194e30f322cb517.png\"\/><figcaption><\/figcaption><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/39c\/3a3\/875\/39c3a3875af667db7b362e500283b634.jpg\" width=\"600\" height=\"398\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/39c\/3a3\/875\/39c3a3875af667db7b362e500283b634.jpg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/cd3\/db3\/912\/cd3db3912bd4b6f658aefee04f5eaf61.png\" width=\"229\" height=\"312\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/cd3\/db3\/912\/cd3db3912bd4b6f658aefee04f5eaf61.png\"\/><figcaption><\/figcaption><\/figure>\n<p><strong>Arduino holder<\/strong><\/p>\n<p>We are going to use Arduino Uno as a processor for our robot. There are many designs of &#171;holders&#187; for this processor, I took one that allows using bolts, but works fine even without them:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d7c\/1fe\/624\/d7c1fe6241580f53391734a9ad5a830f.png\" width=\"318\" height=\"372\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d7c\/1fe\/624\/d7c1fe6241580f53391734a9ad5a830f.png\"\/><figcaption><\/figcaption><\/figure>\n<p>Same holder with Arduino in it:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/45e\/2ce\/ec1\/45e2ceec158395d9895eaf162cc466fc.png\" width=\"311\" height=\"453\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/45e\/2ce\/ec1\/45e2ceec158395d9895eaf162cc466fc.png\"\/><figcaption><\/figcaption><\/figure>\n<p>Arduino in place. As most of parts of our robot, this one is attached to robot&#8217;s base using glue:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/340\/568\/c59\/340568c59bd08f55b2f98a822cd73ff5.png\" width=\"337\" height=\"406\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/340\/568\/c59\/340568c59bd08f55b2f98a822cd73ff5.png\"\/><figcaption><\/figcaption><\/figure>\n<p><strong>Holder for power convertors<\/strong><\/p>\n<p>I am going to discuss electronics later in this article. What you need to know right now is, we will need one MT-3608 power convertor and two LM-317 ones. I have designed a simple holter for them, and placed it on top of the left wheel. On the following picture, red rectangle is MT-3608, while gray boxes are LM-317:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9ec\/d60\/7ce\/9ecd607ce9ce206b3cfb252dcb4cf47f.png\" width=\"444\" height=\"612\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/9ec\/d60\/7ce\/9ecd607ce9ce206b3cfb252dcb4cf47f.png\"\/><figcaption><\/figcaption><\/figure>\n<p><strong>Front wheel<\/strong><\/p>\n<p>One thing I mentioned earlier is the front wheel, a passive (no motor) wheel supporting the front part of our robot. using such wheels is a common design solution in robotic VC, except ours is less elegant. In a production-ready design we probably need to increase its size 2-3, or even 4 times, make a hole in a robot&#8217;s base and immerse that larger wheel in this hole. The larger the wheel, the less are chances that it will stuck at the edge of a carpet or at a trash holder. Once again, this is a common solution in VC design:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/49d\/7d4\/54b\/49d7d454b9ac8547847f08a3b369e3c9.png\" width=\"336\" height=\"369\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/49d\/7d4\/54b\/49d7d454b9ac8547847f08a3b369e3c9.png\"\/><figcaption><\/figcaption><\/figure>\n<p>&#171;Real&#187; VC from the store:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/365\/6b8\/f03\/3656b8f0315dec8823d50255e1eb7b16.jpg\" width=\"600\" height=\"398\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/365\/6b8\/f03\/3656b8f0315dec8823d50255e1eb7b16.jpg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<p>The front wheel in place:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/115\/48d\/beb\/11548dbebbd42b5180749effc0a8a2ca.png\" width=\"559\" height=\"212\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/115\/48d\/beb\/11548dbebbd42b5180749effc0a8a2ca.png\"\/><figcaption><\/figcaption><\/figure>\n<p><strong>Main brush<\/strong><\/p>\n<p>Next thing is the brush. As you might notice, our robot looks suspiciously similar to a VC, so let&#8217;s explain some similarities and differences. The main difference is wheels. We don&#8217;t need to &#171;fight&#187; for sucking power, so we don&#8217;t have to place our robot as close to the floor as we can. So we do not use springs allowing our wheels to propel the robot while its body literally lies on the floor.<\/p>\n<p>The similarities are bumper, overall round shape and&#8230; brushes. We are going to use wet brushes, but the idea of &#171;mopping&#187; the floor with brushes, both side ones and one in the middle, holds. Same way, we want dirt water and occasional dust to be collected in a &#171;dust&#187; bin&#187; we do not use vacuum, but wet brush will pick it from the floor, and as it spins, water will slide off it and to the &#171;dust&#187; bin.<\/p>\n<p>The brush, of course, was bought on Ali:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/1f0\/755\/e58\/1f0755e58a8d6b364b1860149ff2d719.png\" width=\"303\" height=\"507\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/1f0\/755\/e58\/1f0755e58a8d6b364b1860149ff2d719.png\"\/><figcaption><\/figcaption><\/figure>\n<p>As usual (as in VC) the brush is covered by a cylindrical box: we don&#8217;t want drops of dirty water all over our robot as well as around it. Behind the brush, we place a &#171;dust bin&#187;, a &#171;dirt water compartment&#187;. The very fact that brush rotates helps us to direct water outside and to the compartment.  Additionally, we are going to use a spiky &#171;hair collector&#187; to clean the brush (see later).<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/fc5\/514\/453\/fc5514453610c12906b780b5dbf3c2a8.png\" width=\"400\" height=\"306\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/fc5\/514\/453\/fc5514453610c12906b780b5dbf3c2a8.png\"\/><figcaption><\/figcaption><\/figure>\n<p>The brush holder is covered by the lid. As it is very difficult to print brush holder and lid as one part, we print them separately, and connect using glue.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f9b\/9ac\/7fb\/f9b9ac7fb5d0d998dbb71ba9af14bdb6.png\" width=\"378\" height=\"344\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f9b\/9ac\/7fb\/f9b9ac7fb5d0d998dbb71ba9af14bdb6.png\"\/><figcaption><\/figcaption><\/figure>\n<p>Brush should spin, which means we need a motor and a strong one. Mine I got from an old vacuum cleaner, it is a 24V motor with reductor. You can use anything that is strong enough and spins at 2-4 rps.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/2d4\/351\/6e9\/2d43516e9c25bee2ee2017856a44f11e.png\" width=\"404\" height=\"311\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/2d4\/351\/6e9\/2d43516e9c25bee2ee2017856a44f11e.png\"\/><figcaption><\/figcaption><\/figure>\n<p>Note the way motor is connected to the brush. We can not connect it directly, as we don&#8217;t have enough space at the side, so we have placed the motor on top. This is, by the way, why the top of a brush holder is made flat. Also, we use 3 gears, not two. See, I am quite happy with the speed of my motor and i do  not want to increase it. So gears at the motor and at the brush should be the same size. But&#8230;<\/p>\n<p>But if we use large gears, the one at the bottom will scratch the ground! We need a small gear at the bottom, which means we need a small gear on top, too. So we add an &#171;intermediate&#187; gear, its size doesn&#8217;t affect the resulting speed, so I took what I had. It is a bit too large, so I moved it to the side.<\/p>\n<p>Note the way a motor is held in place. <\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/14d\/16f\/3db\/14d16f3db32147f5c39ab74b71910917.png\" width=\"464\" height=\"346\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/14d\/16f\/3db\/14d16f3db32147f5c39ab74b71910917.png\"\/><figcaption><\/figcaption><\/figure>\n<p>This approach is not perfect, because after you glue the motor holder to the brush holder, you will not be able to remove the motor, unless the other end of this assembly can be removed easily (I mean using bolts and nuts, instead of glue). So let&#8217;s take a look at that &#171;other end&#187;. <\/p>\n<p>First of all, gears. There are many ways of holding gears: bearings, plastic or metal axes and so on. I chose metal axes. They are 2mm in diameter and can be pressed in the 2.5 mm holes in gears. The reason holes are larger than axes is in specifics of 3d printing: small holes are imprecise, and a 2.5 mm hole is really something like 1.8. Which is exactly what we need to get a rigid result.<\/p>\n<p>You can make axes by cutting nails, but Ali sells a ready ones, 20mm long, which are perfect for our purpose. Also they sell nylon (I think it is nylon) sleeves. So all we need is to put the sleeve in a hole and put an axe through it.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/e7e\/248\/d52\/e7e248d52a7f2b19a4985f58db74e2b7.jpg\" width=\"600\" height=\"427\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e7e\/248\/d52\/e7e248d52a7f2b19a4985f58db74e2b7.jpg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d52\/1cc\/251\/d521cc251ee38953feb0ce9a9e3d725b.png\" width=\"147\" height=\"213\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d52\/1cc\/251\/d521cc251ee38953feb0ce9a9e3d725b.png\"\/><figcaption><\/figcaption><\/figure>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/0bb\/e0a\/e72\/0bbe0ae727db1d7c364358b55113b4c8.png\" width=\"362\" height=\"583\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/0bb\/e0a\/e72\/0bbe0ae727db1d7c364358b55113b4c8.png\"\/><figcaption><\/figcaption><\/figure>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/be6\/2ff\/91c\/be62ff91c50a650d8ed84f14d52e4d9d.png\" width=\"431\" height=\"513\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/be6\/2ff\/91c\/be62ff91c50a650d8ed84f14d52e4d9d.png\"\/><figcaption><\/figcaption><\/figure>\n<p>Note the pink base of this installation. We are going to glue it to brush holder.<\/p>\n<p>A gears holder, the &#171;other end&#187; mentioned above, is the red part on a picture above. We use bolts to hold it in place, so everything, including motor, can be easily removed:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/845\/5be\/a21\/8455bea214830acadd87995c06162db5.png\" width=\"391\" height=\"575\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/845\/5be\/a21\/8455bea214830acadd87995c06162db5.png\"\/><figcaption><\/figcaption><\/figure>\n<p>The other side of a brush ends with a metal axe 3mm in diameter. All we need is to put it to a printed sleeve:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ae6\/84e\/0bb\/ae684e0bb6d89da873b8298d2a3063a0.png\" width=\"246\" height=\"433\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ae6\/84e\/0bb\/ae684e0bb6d89da873b8298d2a3063a0.png\"\/><figcaption><\/figcaption><\/figure>\n<p><strong>Brush cleaner<\/strong><\/p>\n<p>Now about spiky &#171;hair collector&#187; mentioned above. Attached to the brush holder so that spikes are slightly up, it allows water and occasional dust and hair to go from the brush down to a &#171;dirty water collector&#187;. <\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ba5\/3a9\/aeb\/ba53a9aebe033ea14121fe3ae28fa1a0.png\" width=\"177\" height=\"262\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ba5\/3a9\/aeb\/ba53a9aebe033ea14121fe3ae28fa1a0.png\"\/><figcaption><\/figcaption><\/figure>\n<p>Note that the volume of a collector is much less than one of a water basket, after all, some water remains on the floor. I thought about an obvious way of recycling water by getting it from the basket, to the floor, to collector and through the filter back to basket. Well&#8230; This design can work, so if I decide to do it, I will use a small bottle with some cotton, that&#8217;s all.<\/p>\n<p>The &#171;brush cleaner&#187; (here, I finally came up with the name for it) is attached using glue:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e22\/60f\/3dc\/e2260f3dcfb0d6009e1373cd69ff524f.png\" width=\"344\" height=\"490\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e22\/60f\/3dc\/e2260f3dcfb0d6009e1373cd69ff524f.png\"\/><figcaption><\/figcaption><\/figure>\n<p><strong>Peristaltic pump<\/strong><\/p>\n<p>The idea of our cleaning process is to pump some water or cleaning solution under the front brushes, drop by drop, at a reasonably low speed. We are going to achieve it using so called peristaltic pump, a low speed high precision liquid pump. It is possible to print the thing, but they are available at Ali by a really small price, so we better use a factory build device.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/943\/741\/b66\/943741b6616d66c727e0b3443ba73924.png\" width=\"539\" height=\"485\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/943\/741\/b66\/943741b6616d66c727e0b3443ba73924.png\"\/><figcaption><\/figcaption><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d2f\/8cc\/e77\/d2f8cce7753d3c449bb1bc8600f99626.png\" width=\"600\" height=\"413\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d2f\/8cc\/e77\/d2f8cce7753d3c449bb1bc8600f99626.png\"\/><figcaption><\/figcaption><\/figure>\n<p>To connect the pump with basket of water on one side and with spots on the robot&#8217;s base, where we want the water to be delivered, we will use 1 mm PTFE pipes (Ali again), splitters (we need to bring water from one pump to two front brushes) and silicon pipe to connect PTFE with splitter:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/faf\/145\/a15\/faf145a1564ab93d34013cb4d15ea1b0.png\" width=\"464\" height=\"444\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/faf\/145\/a15\/faf145a1564ab93d34013cb4d15ea1b0.png\"\/><figcaption><\/figcaption><\/figure>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ace\/917\/407\/ace9174074de9353413dc99b0e9a7094.png\" width=\"99\" height=\"99\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ace\/917\/407\/ace9174074de9353413dc99b0e9a7094.png\"\/><figcaption><\/figcaption><\/figure>\n<p>There are, as usual, many ways of attaching peristaltic pump to a robot. We are going to use &#171;quick and dirty&#187; one: tie the pump to a small rectangular piece of plastic, and glue that plastic to the brush holder. This is probably not the best approach, so in future versions it should be improved.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/94f\/4fe\/508\/94f4fe508946de83fadc26bd5d28d2e8.png\" width=\"405\" height=\"204\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/94f\/4fe\/508\/94f4fe508946de83fadc26bd5d28d2e8.png\"\/><figcaption><\/figcaption><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/3f6\/edc\/0d0\/3f6edc0d047431bc30c6a85a8811a514.jpg\" width=\"600\" height=\"398\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/3f6\/edc\/0d0\/3f6edc0d047431bc30c6a85a8811a514.jpg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<p><strong>Connect front and back<\/strong><\/p>\n<p>Now we use printed connector to join brush compartment with the front part of our robot.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c4c\/0cd\/a5a\/c4c0cda5a5ba61c3ff794ad15bb42f00.png\" width=\"252\" height=\"416\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c4c\/0cd\/a5a\/c4c0cda5a5ba61c3ff794ad15bb42f00.png\"\/><figcaption><\/figcaption><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/0da\/720\/50e\/0da72050ea8a9f1f57af7acd4da02b97.jpg\" width=\"600\" height=\"398\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/0da\/720\/50e\/0da72050ea8a9f1f57af7acd4da02b97.jpg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<p>The robot, view from top:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d5e\/0bf\/19b\/d5e0bf19b292bf242fa521ba3ce3762d.png\" width=\"451\" height=\"449\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d5e\/0bf\/19b\/d5e0bf19b292bf242fa521ba3ce3762d.png\"\/><figcaption><\/figcaption><\/figure>\n<p>The &#171;real thing&#187;:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/7c0\/7a4\/75f\/7c07a475fd26e5f9fc32932254e2202b.jpg\" width=\"600\" height=\"571\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/7c0\/7a4\/75f\/7c07a475fd26e5f9fc32932254e2202b.jpg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<h2>Electronics<\/h2>\n<p>We use the following schematics:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/8d4\/629\/d1b\/8d4629d1b094c340076ef29d4012ca29.jpg\" width=\"825\" height=\"600\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/8d4\/629\/d1b\/8d4629d1b094c340076ef29d4012ca29.jpg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<p>It all begins with 19.2 V power coming from the battery. The power switch has 3 contacts, but any switch that has &#171;on&#187; and &#171;off&#187; will do.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/bba\/7df\/450\/bba7df450195d848e4d9f4789950bc90.jpg\" width=\"250\" height=\"726\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/bba\/7df\/450\/bba7df450195d848e4d9f4789950bc90.jpg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<p>Then we feed this power to 3 power convertors: a step up convertor produces 24V for the main brus motor, and two step down LM-317 convertors provide 9V for Arduino and 6V for small brushes and peristaltic pump.<\/p>\n<p>The use of two types of power convertors is due to the fact that to get 24V we need a step UP convertor, while to get 6 and 9V, we need a step down one.<\/p>\n<p>We use double relay (which means two relay, independent but in one body) to control brushes, one relay for small brushes and another one for a large brush (6 and 24V). Note that in a &#171;real&#187; device I remove realys completely, as brushes should always spin, so there is no real need to control them. Same with a peristaltic pump (it is not shown on the schematics, but if it was, it would be connected to 6V relay, or directly to 6V power converter, parallel to small brushes). Why would we need relays then? For a simple reason: say, we want to make a &#171;smart&#187; floor washer, one that at some point shuts brushes and the pump down and begin looking for a charger. As current implementation doesn&#8217;t have that functionality, well, no relays.<\/p>\n<p>Arduino controls relays via pins Gnd and 11, if we don&#8217;t use relays, those wires should not be used (obviously).<\/p>\n<p>Next thing we need to study in details is sensor array. We have 3 buttons (1K each), &#171;pulling&#187; corresponding pins (2, 3 or 4), depending which button is pressed. Buttons can be pressed simultaneously, like front and left ones, why not?<\/p>\n<p>The L293D controller is used to work with motors (wheels). Arduino itself can not provide sufficient current to power up those motors, so this controller takes signals from arduino and power from the power source (rather than from Arduino). Motors are shown next to it, connected to Out1, Out2, Out3, Out4.<\/p>\n<p>Arduino controls L293D via pins 5, 6, 7 and 8, 9, 10, setting the direction wheels rotate and speed. We will discuss it in the programming section.<\/p>\n<p>The only thing that remains to be discussed is the way we power our Arduino. There are few ways, as you can find in the documentation on <a href=\"https:\/\/arduino.org\" rel=\"noopener noreferrer nofollow\">Arduino site<\/a> as well as on the net forums. However, feeding power through the barrel is the safest one. So we plug our 9V power to Arduino&#8217;s &#171;barrel&#187;.<\/p>\n<p><strong>Shield for motors controller<\/strong><\/p>\n<p>Earlier, we discussed the use of L293D controller. Now, we need to connect it to Arduino, motors and power source, and &#171;just wiring&#187; would be messy. We need a shield.<\/p>\n<p>By shield I mean a holder for the chip and (optionally) some of its peripheral electronics, contacts, connectors and so on. In our case we are going to attach shield directly to Arduino, avoiding the need to connect 6 Arduino&#8217;s pins to the L293D chip.<\/p>\n<p>First, we take a foiled getinax. it is a heat resistant plastic with copper foil glued to it. We use hydrogen peroxide method to remove extra copper:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/632\/92c\/8ea\/63292c8eaba4cf971ec4a41d29b42793.jpg\" width=\"600\" height=\"474\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/632\/92c\/8ea\/63292c8eaba4cf971ec4a41d29b42793.jpg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/c8b\/713\/e7d\/c8b713e7da6bc1812a6a53ca9ffd4542.jpg\" width=\"600\" height=\"740\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c8b\/713\/e7d\/c8b713e7da6bc1812a6a53ca9ffd4542.jpg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<h2>Programming<\/h2>\n<p>Arduino controls our robot, so we need a program to control Arduino. As this is not a programming tutorial, we are not going to implement advances approaches, limiting ourselves to a version of simple bump-and-run algorithm. You can find an algorithm designer on <a href=\"https:\/\/robotics.snowcron.com\" rel=\"noopener noreferrer nofollow\">Snowcron Robotics site<\/a>, so you can create rather complex ones, but&#8230; We simply don&#8217;t need it for a primitive robot like that.<\/p>\n<p>To create a project, download Arduino software from the official site, run arduino.exe and use menu to create a new project. Call it &#171;FloorWasher&#187;.<\/p>\n<p>Arduino&#8217;s project may include few files, one (main) should have an extension &#171;.ino&#187;. In our case it is going to be &#171;FloorWasher.ino&#187; Let&#8217;s examine the code, line by line.<\/p>\n<p>First, we need to include the library (comes with Arduino or can be downloaded from the net) that allows us to control motors via L293D, it includes both speed and rotation direction, as well as acceleration\/deceleration to the defined speed. The include file is TrackMotor.h. I am pretty sure I got it from somewhere, rather than writing it, but I wasn&#8217;t able to find the source.<\/p>\n<pre><code> #ifndef TRACK_MOTOR #define TRACK_MOTOR  #include \"Arduino.h\"  enum { MOTOR_FORWARD, MOTOR_BACK };  class TrackMotor {     public:         int m_nEnableMotorPin; int m_nRunMotorForwardPin; int m_nRunMotorBackPin;           TrackMotor(int nEnableMotorPin, int nRunMotorForwardPin, int nRunMotorBackPin)         { m_nEnableMotorPin = nEnableMotorPin; m_nRunMotorForwardPin = nRunMotorForwardPin; m_nRunMotorBackPin = nRunMotorBackPin;  \/\/ ---              pinMode(m_nEnableMotorPin, OUTPUT); pinMode(m_nRunMotorForwardPin, OUTPUT); pinMode(m_nRunMotorBackPin, OUTPUT);   }            \/\/ ---            void enableMotor(bool bActive)         {             digitalWrite(m_nEnableMotorPin, bActive == true ? HIGH : LOW);         }  \/\/ ---  void runMotor(int nDirection) { if(nDirection == MOTOR_FORWARD) { digitalWrite (m_nRunMotorForwardPin, HIGH); digitalWrite (m_nRunMotorBackPin, LOW); } else if(nDirection == MOTOR_BACK) { digitalWrite (m_nRunMotorForwardPin, LOW); digitalWrite (m_nRunMotorBackPin, HIGH); }             else enableMotor(false); }           };  #endif \/\/ TRACK_MOTOR<\/code><\/pre>\n<p>The code is simple: perform current operation until its timer is not over, then make next operation current, and assign a new next operation.<\/p>\n<pre><code>\/\/ Include class that wraps motor functionality #include \"TrackMotor.h\"  \/\/ Possible states of the robot enum { MOTORS_OFF, MOTORS_ON, MOTORS_FORWARD,  MOTORS_BACK, MOTORS_LEFT, MOTORS_RIGHT };  \/\/ Pins (compare to schematics) controlling motors. TrackMotor motorLeft(5, 7, 6); TrackMotor motorRight(8, 10, 9);  class Motors {     public:         \/\/ We keep the robot's state and next state.  \/\/ For example, run forward for 10 seconds (current state),  \/\/ then turn left (next state)         int m_nState;         int m_nNextState;          \/\/ Max. time to perform the current operation. If we hit \/\/ an obstacle, the time will be less than max.         int m_nTimeout;          \/\/ Time when the prev. \"update\" was. We keep absolute time \/\/ for the operations (like \"turn left for 1 sec.)\"         unsigned long m_nPreviousMillis;          \/\/ Bumper's pushbuttons status         int m_btnLeftState;         int m_btnCenterState;         int m_btnRightState;  \/\/ Pins for the sensors (buttons)         int m_btnLeftPin;         int m_btnCenterPin;         int m_btnRightPin;                  Motors()         {             m_nPreviousMillis = 0;              m_btnLeftState = 0;             m_btnRightState = 0;              m_btnLeftPin = 2;             m_btnRightPin = 3;             m_btnCenterPin = 4;                          pinMode(m_btnLeftPin, INPUT);                pinMode(m_btnCenterPin, INPUT);             pinMode(m_btnRightPin, INPUT);              m_nTimeout = 0;             m_nNextState = MOTORS_LEFT;              \/\/ We turn motors on and move forward             setState(MOTORS_ON);             setState(MOTORS_FORWARD);         }            \/\/ ---            void setState(int nState)         {             m_nState = nState;             switch(m_nState)             {                 case MOTORS_ON:                     Serial.println (\"Enabling Motors\");                      motorLeft.enableMotor(true);                     motorRight.enableMotor(true);                      break;                  case MOTORS_FORWARD:                     Serial.println (\"Motors Forward\");                      \/\/ Go forward for max. 20 seconds                     m_nTimeout = 20000;                      motorLeft.runMotor(MOTOR_FORWARD);                     motorRight.runMotor(MOTOR_FORWARD);                      break;                  case MOTORS_BACK:                     Serial.println (\"Motion Backwards\");                     m_nTimeout = 500;                      motorLeft.runMotor(MOTOR_BACK);                     motorRight.runMotor(MOTOR_BACK);                      break;                  case MOTORS_LEFT:                     Serial.println (\"Turning Left\");                     m_nTimeout = 1000;                      motorLeft.runMotor(MOTOR_BACK);                     motorRight.runMotor(MOTOR_FORWARD);                      break;                  case MOTORS_RIGHT:                     Serial.println (\"Turning Right\");                     m_nTimeout = 1000;                      motorLeft.runMotor(MOTOR_FORWARD);                     motorRight.runMotor(MOTOR_BACK);                      break;                  case MOTORS_OFF:                 default:                     Serial.println (\"Disabling Motors\");                      motorLeft.enableMotor(false);                     motorRight.enableMotor(false);                      break;             }         }            \/\/ ---          void update()         {             unsigned long currentMillis = millis();             if(m_nPreviousMillis == 0)                 m_nPreviousMillis = currentMillis;                              \/\/ If the pushbutton is pressed, buttonState is HIGH.             \/\/ Whatever happens, we begin by moving back.             if(m_btnLeftState == HIGH) { Serial.println (\"Left button pressed: Moving Back\");                 m_nPreviousMillis = currentMillis;                 m_nNextState = MOTORS_RIGHT;                 setState(MOTORS_BACK);             }             else if(m_btnCenterState == HIGH) { Serial.println (\"Central button pressed: Moving Back\"); m_nPreviousMillis = currentMillis; m_nNextState = MOTORS_LEFT; setState(MOTORS_BACK);             }             else if(m_btnRightState == HIGH) { Serial.println (\"Right button pressed: Moving Back\"); m_nPreviousMillis = currentMillis; m_nNextState = MOTORS_LEFT; setState(MOTORS_BACK); }                         else if(m_btnLeftState == LOW &amp;&amp; m_btnCenterState == LOW  &amp;&amp; m_btnRightState == LOW                  &amp;&amp; currentMillis - m_nPreviousMillis >= m_nTimeout)             {                 int nState = m_nNextState;                                  if(m_nState == MOTORS_LEFT || m_nState == MOTORS_RIGHT)                 {                     Serial.println (\"Buttons released\");                     m_nNextState = MOTORS_FORWARD;                 }                 else if(m_nState == MOTORS_BACK)                 {                     Serial.println (\"Finished going back\");                     m_nNextState = MOTORS_FORWARD;                 }                 else if(m_nState == MOTORS_FORWARD)                 {                     Serial.println (\"Finished going back\");                     m_nNextState = MOTORS_LEFT;                 }                                      m_nPreviousMillis = currentMillis;                                  setState(nState);             }         }  } motors;  \/\/ ---  void setup() {     Serial.begin (9600); }  \/\/ ---  void loop()  {     motors.m_btnLeftState = digitalRead(motors.m_btnLeftPin);     motors.m_btnCenterState = digitalRead(motors.m_btnCenterPin);     motors.m_btnRightState = digitalRead(motors.m_btnRightPin);        motors.update(); }<\/code><\/pre>\n<h2>Video.<\/h2>\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/5ffacc5005d782142ffea583\" data-style=\"\" id=\"5ffacc5005d782142ffea583\" width=\"\"><\/div>\n<\/p>\n<\/p>\n<\/p>\n<\/p>\n<\/p>\n<\/p>\n<p><a href=\"https:\/\/robotics.snowcron.com\" rel=\"noopener noreferrer nofollow\">Home of this article <\/a><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/536338\/\"> https:\/\/habr.com\/ru\/articles\/536338\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>When we think about robots, the first thing that comes to mind are robotic vacuum cleaners. The reason is simple: they are the most &#171;solid&#187; demonstration of success of &#171;consumer&#187; robotics. So making one sounds like a good idea&#8230; at first.<\/p>\n<p>But isn&#8217;t it a bit counter productive &#8212; to build something that popular, something we can buy in a store at a commodity (small) price? Should we build something similar, but NOT a vacuum cleaner? Something like&#8230; a floor washer, perhaps? Yes, a robotic floor washer.<\/p>\n<p>In this tutorial I am going to build a fully working prototype of a robotic floor washer. By &#171;fully working&#187; I mean that it is going to wash floor, instead of moving dirt around like most robotic &#171;moppers&#187; do. While by &#171;prototype&#187; I mean it is going to be the first step towards production-ready unit, but not a production-ready unit yet. Let me explain.<\/p>\n<p>First of all, it is not going to be THAT solid. You can grab a robotic vacuum cleaner that you got from the store by any part, including wheels and bumper and lift it. It will not fall apart. Ours probably will. The reason is, to make a device &#171;mechanically solid&#187; is a separate task, and if we focus on it, then &#171;robotic&#187; tasks will become more difficult to achieve. So we are going to do what engineers usually do: first  they build C3PO without the outside body, wires everywhere and so on. And only then they put a gold-covered outfit on it.<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>Other than &#171;solidity&#187;, we are going to make some more simplifications, compared to a production ready unit. First, we&#8217;ll use Arduino. It is an insanely popular universal processor, but if you open a vacuum cleaner from the store, you&#8217;ll see a specialized processor instead. Obviously, it is cheaper to produce and to fix, but it is harder to design.<\/p>\n<p>Second, we are not going to pay any attention to layout of wires. This is acceptable for a simple prototype (ours is simple, by the way), but a hundred percent show stopper when it comes to production. But this is a tutorial, not a final spec.<\/p>\n<p>Finally (and it is closely related to our decision to not make the prototype &#171;solid&#187;) we are not going to make it compact. The reason is obvious: when you need access to something, you should get it in one step. Try getting into a vacuum cleaner you got from the store, and you will see what I mean.<\/p>\n<p>However, this all said, the prototype will do what it is supposed to do, and can be considered as, well, a prototype. The next step (one I am going to skip) would be building a production-ready unit based on it.<\/p>\n<\/p>\n<h2>Mechanical Part<\/h2>\n<p><strong>Base<\/strong><\/p>\n<p>Before we begin, we need to figure out what is it we are going to build. As you saw before (compare <a href=\"https:\/\/robotics.snowcron.com\/vc_platform_1\/vc_platform_1.htm\" rel=\"noopener noreferrer nofollow\">VC Prototype 1<\/a> and <a href=\"https:\/\/robotics.snowcron.com\/vc_platform\/vc_platform.htm\" rel=\"noopener noreferrer nofollow\">VC Prototype 2<\/a>), there are many ways of moving a mop around the room. As we want to build a programmable device and not a mechanical toy, we are going to choose a &#171;round design with a bumper&#187;.<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>We are going to build a 360 mm diameter circular design.<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>As I mentioned many times in my tutorials, you can use almost any materials and tools. However, if you are serious about robotics, you should consider buying (it is about $100) or building (<a href=\"https:\/\/reprap.snowcron.com\" rel=\"noopener noreferrer nofollow\">Reprap DIY<\/a>) a RepRap printer. By the way, building a 3d printer is not that hard and is definitely easier than building a robotic vacuum cleaner.<\/p>\n<p>So I am using a 3d printer. What does it mean for my design? <\/p>\n<p>The size. A reprap can print objects of the 200 x 200 x 300 mm, so to pring the base of our Floor Washer, we need to cut it in CAD designer program and then to glue it together (I do it by glueing plastic bande to the bottom of the connection line.<\/p>\n<p>As for the CAD software, I am going to use <a href=\"https:\/\/tinkercad.com\" rel=\"noopener noreferrer nofollow\">Tinkercad<\/a>, a simple and very nice online designer.<\/p>\n<p>So, here is the base for our robot, with technical holes and space for wheels and other peripherial staff:<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p><strong>Wheels<\/strong><\/p>\n<p>Next, we want to attach wheels. We are going to use cheap motors from Ali store, you can, of course, replace them with whatever you can obtain from broken toys. The only requirement is voltage (we use 6V, but it is adjustable) and speed (we need our robot to be 2-3 times slower that a robotic VC would be).<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>3d printer allows you to print virtually anything, so our wheels have nice holes (that serve no purpose aside from being nice) and slots on the outer part.<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>The reason we use those &#171;slots&#187; is friction. Plastic wheel slides on a dusty floor, and so does rubber, if it is covered with dust. So we need to increase adhesion somehow. A simple approach is to put soft regular objects on the wheel, in this particular case, I use fragments of the line I got from the jumping ropes:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>Note the way we use the large gear to additionally reduce speed of the motor.<\/p>\n<p><strong>Wheel motors and gears<\/strong><\/p>\n<p>In our particular case, we use nuts hot-pressed (with soldering iron) into the gear to make sure axes are attacher properly and will not slide&#187;<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>Now, the green box around gears should, in a production-ready design be solid. Here, however, it has holes, to make easier to see what is going on inside and to make it possible, if necessary, to reach inside with a pin set.<\/p>\n<p>Gears are being held using bearings, placed in the cylindrical holes in the gear box:<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>The gear is too large to fit above the Floor Washer base, so we need to cut hole in it. Of course, we can not use it like that, the gear will be covered with dust, hairs and become stuck. So later we will print a cpecial box to cover the bottom of the gear:<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>Now, there was an intentional error in an image of motors above. We are going to use glue a lot here (while prodiction unit will use bolts), so if we put motors between motor holding box and gear holding box&#8230; We will not be able to remove it, without breaking the glue. So we turn the motor holder boxes around:<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p><strong>Water basket<\/strong><\/p>\n<p>The next step is installing the box with water. I used one I got in a grocery store. The reason we put it in place now is that it is large, and all other objects should be placed around it, or at least with it in mind. On the picture you can see click-fit holders that keep the box in place, in an actual device I used glue (which is cheating).<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p><strong>Side brushes<\/strong><\/p>\n<p>Next, we need side brushes. We use small motors with reductors from Ali, that are surprisingly good for this purpose:<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>We also use ready side brushes (Ali again):<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>As you can see, we need a larger hole on the robot&#8217;s base:<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>We need to lift the motor so that brush is half-immersed in the base:<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>Of course, in the production-ready design this &#171;box&#187; should be made smooth, following the shape of the top of a brush. This looks nicer, but doesn&#8217;t affect anything in terms of usability.<\/p>\n<p>Now, we are going to place a motor on top of that &#171;box&#187; and to cover it with a &#171;holder&#187;. That way motor can not move up or down, neither can it spin. We can attach brush to it by simply pushing from below:<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>This is what side prushes look when they are in place with their motors:<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p><strong>Bumper<\/strong><\/p>\n<p>The next step is a bumper of course. As was mentioned before, 3d printer has size limitations, so we print parts and then glue them together:<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>Note that in this design I added 3 slots for ultra sonic sensors. The way they are usually used in &#171;normal&#187; VC is, to detect a wall in advance, and to drop the speed, so instead of a loud collision we have a soft touch. However, to make washer to wipe the floor better, I had to reduce the speed about 3 times, so  sensors are not necessary. It moves slow enough already:<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>Note the way shields of the bumper overlap to increase total rigidness of the structure:<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>Last shields on the right and left sides have different shape: in theory, it should reduce incidents when the robot turns and left\/right end of a bumper hits the obstacle.<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>In a production-ready unit this sort of incidents should be excluded by precise design:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p><strong>Bump sensors<\/strong><\/p>\n<p>Next, we need sensors that detect the fact that bumper was moved. Leaving design specifics aside, they are nothing but clickable buttons:<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>We are going to install 3 sensors: two on top of wheels at the sides of our robot and one in front.<\/p>\n<p>Side sensors have to be lifted up so that they are on top of the wheel:<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>When the corresponding side of the bumper hits the obstacle, it moves towards the sensor and presses it, as it is nothing but a pressable button:<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>As for the front sensor, we lift it just slightly using U-shaped plastic holder. It is located at the center (or almost at the center) of a bumper. The following image shows the central sensor, to make it easier to read, I moved the bumper forward a bit.<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>Note the &#171;almost&#187; above. It is a common situation in mechanical design, when we need to place more than one device at the center (corner, top etc) of our robot. In our case, the holder of a bumper should be at the center line, as well as the sensor: what should we do?<\/p>\n<p>Well, we should ask ourselves &#171;should it really be EXACTLY at the center line, and if the answer is &#171;no&#187;, we should move it few centimeters to the side.<\/p>\n<p>So, as we mentioned the bumper holders, let&#8217;s discuss them. Earlier, in <a href=\"https:\/\/robotics.snowcron.com\/vc_platform_1\/vc_platform_1.htm\" rel=\"noopener noreferrer nofollow\">VC Prototype 1<\/a> I &#171;invented&#187; a simple mechanical schematics, allowing the bumper to move as we need it to, and preventing it from swinging to the sides and doing other unwanted sort of things. That design was ok, but printing it (or making it by hand) was tricky and it didn&#8217;t look nice. So for this project I have &#171;invented&#187; another one, which is kind of nicer. Note the quotes around &#171;invented&#187;: I am pretty sure it have been invented many times before me; luckily, I am not using this design to actually produce robots. Otherwise, your patent lawyer should probably make sure it is financially safe.<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>As you can see, this simple device can extend\/collapse along horizontal axe, but is rigid enough to NOT bend up or down: just what we need from our bumper. Once again, we are going to hold bumper &#171;in the air&#187; using 3 devices like at the picture above (left, center and right ones).<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>If you think about it, this design is insufficient. What if we move the bumper to the side, like at the image we presented earlier?<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>If the obstacle presses against the end (left or right) of a bumper and we only have holders presented on pictures above, it (the<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-413469","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/413469","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=413469"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/413469\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=413469"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=413469"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=413469"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}