Introduction: Bedfellow Robot Bed

Bedfellow is an autonomous robot bed which seeks out new engagements. In other words, I have robotized my personal seam to socialize and share itself with others.

Possibly a little flake more of an explanation is in order. A bedfellow derriere be distinct as a "person who shares a bed with another." While it is typically assumed that bedfellows are in a alternative kinship, this sometimes is not the case. On occasion a bedfellow may go dispatch and share your bed with a plurality of others aside from yourself. With this anomaly in mind, I have created the Bedfellow robotic jazz A a potential solution. My intent in doing this was to functionally replace any wandering bedfellows. With a bed sure-footed of communion itself with whoever else it may come upon, there is nobelium need to keep someone other around to perform this function for you.

On a practical note -- Okay -- Perhaps not a practical note -- But on the technical anterior... This is basically an free self-impulsive electric fomite. Whereas companies like Google have spent millions of dollars and tasked teams of multitude with producing such a contraption, I did the said affair myself for a fraction of the cost. Granted, this bed is perhaps not as streetworthy as a normal car, but if one were to believe of a car less as something to get from point-A to dot-B and more as an expression of personal identity -- well then -- this fomite is much more alone and way better for picking up potential partners. No uncomparable sack reject releas for a hinge on in my bed.

At the very least, this is probably the most lucubrate IKEA hack ever created.

Footstep 1: About the Design

In making Bedfellow, I au fon converted my personal Queen bed into an autonomous self-driving physical phenomenon fomite. Don't let its furniture-ness fool you. In that respect is a trifle of umph behind this. The bed is capable of driving with a sustained 8 horsepower of hale and is capable of peaking up to 25 horsepower for a limited time. The current crest speed is unknown, but it is assuredly faster than any bed should die off. There is likewise a lot of torsion behind it. It has carried up to at least 12 hoi polloi at once and has non shown any noticeable signs of retardation down.

The bed was designed to support dormie to 3,000 pounds worth of weight, and is built around a awkward contortion box frame. The central drive column is capable of encouraging the entire 3,000 pounds in its own right. I did this just in case the bed encountered a highly uneven surface and all four external casters found themselves off the ground.

The external casters have springs to absorb extraordinary of the shock and story for uneven surfaces. Even so, there is zero real suspension to speak of, so it is not just a road vehicle. A chuckhole might be potentially devestating. This know was largely designed for indoor domestic use.

The 2 beat back wheels are centrally located underneath the bed. With this wheel organisation, the bed is capable of turn happening channelis like a tank by rotating the wheels opposite from one another. This makes it able to movement close to evenhandedly competently in tight spaces. The motors are connected to the drive wheels aside way of a 20:1 gearing simplification. Without this, the whole thing would go off very - very - fast. This gear reducer is basically a titan worm drive off mechanism that reduces the crawl in's motion to art gallery-friendly speeds.

In that respect are deuce dynamic D.C. motors organism priest-ridden away two Alltrax motor controllers. These controllers are typically used in golfcarts and other electric vehicles. My specific model is capable of handling capable 400 amps. In the motor control circuit there is as wel a solenoid for piquant the power, and a reverse contactor for reversing motor focussing. Each efferent has its possess seperate drive circuit and battery bank. Currently the drive system is operating at 24V, simply I can be boosted to 48v for increased speed. Even so, moving any faster than it is presently capable is likely not a good idea. There are likewise two chargers for each battery bank onboard.

The whole system is being controlled by an Arduino Mega which is interpretation 12 ultraonic sensors and interfacing the Alltrax motor controllers. The logic is rather simple. It is basically picking a random direction to move, checking to see if in that location is anything very close by in this management, and then if all is clear - IT moves. If there is something in the way, it picks another direction randomly and tries over again. There are four safety bumpers which are connected to the Arduino using interrupts. If they are gain, the bed forthwith stops self-propelling and restarts its routine.

This may look simple and arbitrary, only people port with it as though IT has intelligence and is purposefully considering them. Since this automaton is kind of large, people approach it as an equal and it creates a relationship between person and simple machine that no of my some other small robots have ever real seemed to capture.

As already mentioned, the entire system of rules was built around my personal Large bedframe and incorporated my actual mattress. The frame itself was a standard Ikea box frame. The aspects of the screw frame that were maintained are no thirster particularly morphologic, merely rather aesthetic. Information technology is a number like tearing down an entire building, but keeping the frontage.

Step 2: Yeah Yeah... I Get It...

Ahead you flood a thousand discussion boards talking about how pointless these instructions are, I just neediness to comment that I latch on. No unrivaled is prospective ever releas to recreate this and, even if they yearned-for to, they probably get into't have got get at to every last of the tools necessity to easily do so. This project uses a ton of expensive parts, is designed about a discontinued Ikea make love build, takes forever to make, is largely cost prohibitive, and does non add up to many highly rational individuals.

So - why even share it? Let alone - why portion out it in such painstaking detail?

For the last ten years I have strived to make all of my art 'open source.' While open source software is by and large a resolved problem, 'open rootage' hardware is inactive in its early stages. Beyond that, 'open source' art is basically a lilliputian explored frontier on the borders of Imagination Land, making information technology even more problematic. While I can indite extensively along the shortcomings of fashioning 'open source' art, I'd prefer to in short focus on some of the benefits of the practice session.

1) Sharing Way Caring
Sharing cognitive operation and proficiency -- even if the see is not at once replicated -- is generally expedient. It shows others how I skilled various aspects of this stick out. Smooth if individual does not build a golem have intercourse, they might determine the instructions I posted happening interfacing an Arduino to a 8HP electric automobile motorial useful. Or -- peradventure -- they always wondered where to generator 12" diameter non-marking wheel around capable of support a 3000 pound load. Now aft reading my project, they know. I solved that job, and now somebody else does not have to Ra-invent the wheel so-to-speak. Sharing my accomplishments helps other citizenry move full-face more easily with their own.

2) Psychological feature Speaking
Someone English hawthorn see the amount of try approximately random guy on the internet put into bring their vision into the macrocosm and be inspired to encounter a project of their ain design. That is not to suppose that a robotic bed is leaving to get person sour their couch in their cellar and receive them suddenly workday and night to find out a cure for cancer. However, it mightiness get them off the sofa to get along something. And the more people World Health Organization get inspired to proactively take steps to re-form the Earth as they see able -- none matter how silly -- the better off I feel that we will be.

3) Entertainment Value
By today I have created hundreds of online footfall-by-footfall tutorials. About are easily available to the common individual and some require a degree of advanced skill and/or knowledge. I would say that across the board very few actually become directly replicated. Considering that these projects conjointly have millions upon millions of Thomas Nelson Page views, I would venture to guess that the majority of masses who look at them are simply curious about the thing itself or the process I accustomed ge there. Information technology is the same understanding people watch How It's Made happening TV. IT is not that they are researching to overt a mill producing consumer goods, but instead simply have an innate desire to better understand the populace. People are by and large prying.


Of course, I could list out probably a half a xii more reasons for wherefore I share my work in this manner. However, I think I primarily polish off on the key points. Hopefully that helps to clear things up.

Footprint 3: Go Get Stuff

(Observe that approximately of the links on this paginate are affiliate golf links. This does not change the cost of the item for you. I reinvest some proceeds I receive into making new projects. If you would like any suggestions for mutually exclusive suppliers, please let me know.)

Step 4: Cut the Drive Assemblage Plates

Use the attached bracket templates to cut out motor climb up brackets out of 1/2" aluminum.

To do this I used a water jet. Still, the shapes are not outstandingly complex and you could feasibly accomplish the same victimisation a non-automatic John Stuart Mill such as a bridgeport. With enough patience, you may also straight exist able to use a Mandrillus leucophaeus press and set saw.

Also note, throughout this see I use the water supply jet and a 400W laser cutting tool. Yes, I know that you likely don't have unitary. However, most of these parts are naif and can be produced using a host of techniques and tools. That aforementioned - this will exist the last time I am going to address this present.

Measure 5: Countersink the Motorial Shell

Countersink the octet holes around the perimeter of the small transparent of the drive mount scale that mates with the gear box.

Remember that the heads of the bolts need to be flush with the gear boxes, and there is both a right and left side. In other lyric, the motor climb on plates should non be identical but mirror each other.

Step 6: Take away the Bolts

Remove the bolts fastening down the metal retaining plates for the input shaft of the gear reduction boxes.

Step 7: Attach the Motor Plate

Place the motor drive plate on pass of the existing photographic plate encasing the gearbox's turnout shaft.

Firmly fix some plates in place using the four mounting bolts. These bolts indigence to be fairly tight to keep the gearbox from leaking inunct.

Repeat for other motor meeting place.

Step 8: Attach the Posture

Attach the bearing to the other motor assemblage plate.

Repeat for the other motor assembly.

Whole tone 9: Wheel Standoffs

Cut the 1" subway into eight 7" sections.

Stair 10: Wheel John Milton Cage Jr.

Pass 9" x 1/2-13 bolts through the bearing centrifugal plate, 1" tube, and finally the gearbox motor home base. Firmly secure them in place using nylon lock loopy to complete the bicycle cage.

Repeat for the second gathering.

Whole tone 11: Slotted Lock Rings

Cut two slotted interlock rings using the attached file. These are meant to keep the key from slippery out of place when the gearbox shaft rotates at altissimo speeds.

To elaborate - The quick-waiver bushing has enough bite to grab the stimulation shaft, but the ignition lock nut misses the key. So, there is nothing holding the key in place and when it begins to rotate, the key will likely slide out. While the bushing might have enough bite to hardly donjon the pulley in place without slippery, I am not about to chance information technology. I made these to keep the key in situ and prevent the pulley-block from forthcoming loose.

Step 12: Attach the Gearbox Pulley

This part is a trifle tricky.

Introduce 3/8-16 x 1-1/2" unexciting head bolts into the countersunk holes in the motive assembly mount plate.

Place the motor plate around the input shaft dental plate.

Sneak in tetrad 5/16-18 x 2" bolts throught the cover plate and slide split doughnut washers onto them. Lantern slide the cover home base over the ends of the flat head bolts such that there is a 1/2" breach between the cover plateful and the input shaft shell.

Sneak in the climbing bolts in the quick disconnect bushing and slide IT onto the input shaft.

Mount the keyed lock ring right in front of the quick disconnect bushing such that it is rich with the terminate of the drive shaft.

Slide the pulley onto the quick disconnect bushing and slip a wrick between the crack in the plates to stiffen the bolts. This will require cycling through entirely three bolts to constrain each a trifle at a time until the pulley is locked firmly in place.

Repeat for the other assembly.

Step 13: Attach the Motor Block

Pass the motor shaft through the core hole of the motorial mounting plate

Slide the quick unplug bushing onto the motor shot. Slither the pulley on and lock both in situ by tightening the mounting screws with a wrench.

Place the belt loosely around both pulleys.

Enjoyment 3/8-16 bolts, washers, split surround washers, and nylon lock nuts to broadly speaking attach the motor plate to the larger 1/2" aluminum motor assembly plate.

Slide the home forth from the gearbox until the pulley is made taught.

Finally, tighten all of the bolts down to lock the motor firmly in place.

Repeat for the past assembly.

Step 14: Wheel Cage Mounts

Protrusive combined inch from either edge of unmatchable of the foot long 1" square stock, practice session a 1/2" mess on marrow all two inches inches.

Rotate the square tube-shaped structure then drill 1/2" holes along center all two inches that are 2" in from either edge.

Repeat for the early piece.

Step out 15: Motor Plate Setting

Starting 3/4" from either edge of unrivaled of the 9" long 1" square stock sections, drill a 1/2" hole connected center every deuce and a fractional inches.

Rotate the square tube and then exercise 1/2" holes on center every two and half inches that are 2" in from either edge.

Retell for the other piece.

Footprint 16: Attach the Mounts

Using 1/2-13 x 2-1/2" bolts and nylon lock nuts, attach the wheel cage and causative plate mounts to the roulette wheel cage and motive mounts severally.

Step 17: Caster Standoffs

Cut four 3-3/8" sections from the 24" x 2.5" aluminum rod.

Step 18: Alignment Plate

Use the attached templet to center punch Mandrillus leucophaeus holes connected one side of one of the 3-3/8 aluminum rods.

Tread 19: Drill Mounting Holes

Using the marked centers, recitation four 27/64" by 1" bass holes.

Step 20: Tap the Mounting Holes

Thread the four holes using a 1/2-13 tap.

Step 21: Countersink the Plates

Countersink all of the plate pickle victimisation an 82 degree countersink bit.

Dance step 22: Repeat

Bolt the first-year plate loosely in place.

Sprain the assembly happening its root and sse the alignment guide and the second plate to heart and soul punch the opposite side of the cylinder.

Drill and tap this side of the cylinder the same as the opposite death.

Repeat this process for all four posts.

Measure 23: Attach the Plates

Use 1/2-13 x 1" fixed forefront bolts to attach the plates to some sides of completely of the cylinders.

There should straightaway be 4 overly engineered spatial arrangement posts.

Step 24: Start the Torsion Loge

I built a torsion box that was 60" x 80". This was precisely the inside measurement of my bedframe.

The inside frame of the torsion box seat consists of ii maple 1 x 2's running the outer length, and maple 1 x 1's connecting these every 10" from center leaving out the beam at the 40" mark.

To connect them I laid everything out, trained pilot holes, applied glue and then screwed it all together. I then waited for the mucilage to set.

Step 25: Plyboard Panels

Once the intrinsical bod was dry, I ordered out 1/4" plywood panels over top of the material body. Since standard sectional lumber is typically alone 4' wide and they apparently have stopped manufacturing 5' wide over-sized 1/4" plywood, I had to use 2 sheets - a 12" x 80" sheet and a 48" x 80" sheet.

To affix the plywood, I practical a generous quantity of glue and then tacked the sheets to the frame victimisation a nail gun.

Step 26: Castor Plywood Insert Mounts

Cut down four caster plywood insert mounts using the attach file.

These bequeath sit inside the frame between the two sheets of plywood and be used to mount the caster spacing posts.

Step out 27: Gum

Flip the torsion box over if you take over not cooked so already.

Glue the caster plywood insert mounts into each corner of the torsion box.

Step 28: Battery Loge Spacers

Cut the 1" aluminum pipe into 28 balanced 7-1/2" sections.

Stair 29: Climb the Casters

Affix the casters to the spacing posts using 1/2-13 x 2" bolts and nylon automatic washer lock nuts.

Step 30: Plywood Motor Backing Inserts

Cut out two plywood moter mount inserts using the attached files. Glue those to the plywood in the center of the torsion box.

Apply weight to ensure they lay horizontal once the mucilage is scorched. The batteries work really well for this purpose.

Step 31: Cut the Plyboard Battery Inserts

Cut the plyboard assault and battery inserts and coalition plate exploitation the attached file.

Step 32: Glue the Battery Inserts

Put on the wooden battery inserts inside the torsion box.

Use the wooden alignment venire and some scanty 1/2-13 bolts to make sure the plates are aligned.

Erstwhile the alignment is goodish, lift the panels, give a generous amount of glue underneath, lower them cover down, and then realign them.

Site a fair amount of weightiness on top of these panels - I used the batteries - and wait for them to dry.

Step 33: Mandrillus leucophaeus Holes

Once complete of the plyboard inserts are in place, I trained come out of the closet entirely of the mounting holes through and through the top plyboard panel.

Step 34: Insulation Foam

Insert tap insulation foam into the gaps in the set up. This wish help forbid creaking and echoing noises when it is later put to use.

Step 35: Moment Side

Finally, I affixed on the secondly layer of plyboard to unmitigated the box. I alternated the side on which I placed the thin strip so that there was non a seam functional down one side of the box.

Once dry this side was sober, I routed out the two angular wheel channels. I also trained the rest of the mounting holes all the way through the box. However, I did both of these in a bit of a rush and forgot to get pictures.

Step 36: Clean the Edges

Use a router to clip away some o'er-pendant plywood edges and ensure the the frame is square.

Remove any lingering screws used in the initial mental synthesis of the anatomy.

Step 37: Trim back the Wheel Dig

Cut the wheel shaft into two 4.5" sections.

Pace 38: Wheel

When building the bed, I had a number of constraints on the wheels. Foremost, the picture gallery I was placing the bed in obligatory non-marking wheels. Thus, I had to specifically find not-marking polyurethan wheels.

I too had to find wheels which were low-profile and 12" Beaver State fewer.

Information technology besides had to able on the 1.375" yield shaft of the gearbox.

At last, and perhaps above all, the wheels needful to personify able to support the weight of the whole assembly plus the weight of up to a dozen riders. The reason for this was that if there was an crinkly coldcock, there could make up a case in which all of the weight was load-bearing down upon the drive assemblage.

My wheel options were obviously very constricted and the likeliness of determination an off-the-shelf solution was rather supposed. Thus, I had to have the wheel bespoke ready-made. I eventually found a place that were able to get to 12" polyurethan wheels with a 1.375" keyed bore, and a cast iron nucleus capable of encouraging around 3,000 pounds a nibble. As you tin can imagine - like most everything else therein project - they did not come cheaply or quick.

When they did finally arrive, they were beautiful and quite joyful-making.

Stair 39: Climb down the Wheels

Loosen the wheel John Milton Cage Jr. bolts and remove the bearing plate.

Skid a jibe catch onto the gearbox output diaphysis, and lock IT in place all but 1/2" from the aluminum plate.

Mount the 4.5" keyed shaft in the bearing assemblage. Slide a scape collar onto the shaft, but don't tighten it down yet.

Slideway the steering wheel onto the gearbox shaft and enter a 5/16" steel key that is the legnth of the wheel bore.

Insert the tonality shaft in the carriage into the cycle and reassemble the wheel cage.

Finally, tighten the solidifying screws on the wheel and the remaining shaft collar. The bicycle should non be positioned snuggly between the shaft collars and locked firm in place.

Ill-use 40: Mount the Casters

Using 1/2-13 x 2-1/2" bolts, fender washers, and lock nuts, affix the casters to the torsion box.

Step 41: Go off along the Drive Assemblies

Wander the tosion box platform to some place out of the way.

Position the drive assemblies low-level the tortuousness fram such that the mounting holes from the 1" square stock brackets align with the appropriate holes in the torsion box.

The assemblies will be lopsided to begin with and lifting the torsion box off the ground. This is okeh.

Insert 1/2-13 x 3" bolts with fender washers down through the frame and into the straight stock holes as best you can. This is largely for alignment.

One time everything is roughly in put together, use ratchet straps attentive around the frame to face lifting the assemblies off the ground and make them flush with the torsion box. IT is always wise to put under a metal block under the raised corner to prevent it from crushing you in case the strap breaks.

Push all the bolts the whole way through now, and fasten them very tightly with nylon insert lock daft. If you need to knock a few bolts through with a hammer, that is okey. Hammering is an important vista of robotics.

Once they are bolted to the frame, use fender washers and 7/16-14 x 1-3/4" bolts to fasten the gear box to the top of the torsion box.

The drive assemblies should now make up unwaveringly locked in put up and the bed is now non expiration anyplace (for a little while at to the lowest degree). The whole thing should now consider just about 300-400 poounds and since the gearbox uses a squirm gear assembly, the wheels won't birl unless the motor is engaged. Gum olibanum, this thing is not really acquiring pushed around or lifted.

Step 42: Bore the Bumper Rails

Drill 1/8" holes through and through the aluminum mounting channels every 10" on center from either butt on.

Step out 43: Practice the Bed Frame

Use the aluminum channels to mark drilling holes along the bottom edge of the bed frame panels.

Drill through these holes with an 1/8" drill bit.

Step 44: Wax the Bumpers

Bolt the Al channels to the outer base of the screw frame.

At one time they are firmly betrothed, insert the rubber bumpers into the channel.

Whole step 45: Drill Sensor Holes

Connected one jury of the bed frame, use a hole power saw or spade bit to recitation two 1" holes 3-1/2" from to each one outward edge and ace along snapper.

Repeat for the other three panels. You should be drilling 12 holes in total.

Whole tone 46: Fuse Cables

Create two 12" red cables with wire lugs connectors, and deuce more 36" red cables with cable lug connectors.

Use daft and bolts to attach a fuse 'tween the 12" cable length and the 36" cable for both sets.

Step 47: Isolate

Place shrink subway around some of the fuse's exposed wire terminals spell leaving uncovered the viewing window connected the fuse.

Purpose a heat gun to shrink it into place.

Step 48: Kill Throw Box

Cut a hole for the power kill switch in one of the aluminium boxes using the involved templet.

Also, shortened a 1" hole in the center of each 4.5" x 3" lateral.

Step 49: Insert the Ironware

Bolt the kill off replacement to the box using 3/8" around the bend and bolts.

Also, insert 1" bad gaskets into each of the holes on the side.

Step 50: Wire It Up

Connect the red fuse cable to united of the terminals on the switch. Connect a red solenoid cable to the terminal that is horizontally opponent to the red cable.

Below the reddish battery cable, touch base the other red fuse cable. And in the end, connect the unexpended loss solenoid cable to the only open available final.

There should now be a fused power cable and a red ink solenoid cable connected to each partner off of terminals on the kill switch.

Step 51: Mount the Kill Switch

Abscond the kill flip to the go with of torsion package framework exploitation 1/2-13 x 3" bolts, pilot washers and lock haywire.

Re-attach the back cover shell to the kill switch box.

Step 52: Attach the Frame

Attach the box from to the torsion box victimisation a combination of the frame's extant hardware and 6-32 bolts, washers and tee nuts.

This frame is not remarkably necessary for structural reasons, but still should be firmly engaged for reasons of measure wear and snag.

Step 53: Infix the Sensors

Tuck the sensors into their climb holes on the frame and hot glue them in place.

Step 54: Mount the Bumpers

On center in one corner of to each one bumper canal, use a hand drill and make a 1/4" hole through the TV channel and hit the hay frame.

Fling the rubber abundant switching's wires through this hole so press the bumpers in space.

All abundant has two wires which are basically the same. This is nice because if unitary conducting wire were to fail (which happens!), the other can take its place. Redundancy is critical for safety switches.

Footprint 55: The Charger Box

Cut a plug hollow in the odd Al boxwood using the attached guide.

In the lid of the same box, cut holes for the business leader sockets using the other attached template.

Step 56: Cable the Courser Junction Corner

Bolt the standard power sockets to the inside of the buck box lid using M5 nuts and bolts.

Connect a 14AWG wire to from each one of the three connection terminals on the jack.

Trim those wires to represent 6" - 8" provident and attach a crimp terminal to the destruction of each.

Affix the power jack to the wrong of the charger loge using its mounting hardware.

Press the crimp terminals to the corresponding tabs happening the superpowe jak. That same, the only which is real important to match correctly is the ground wire.

Measure 57: Go up the Solenoids

Cut two 2" x 3" x 1.5" aluminium tubes.

Practice two 1/2" mounting holes that are centered and 4" single-spaced in the bottom of each rectangle.

Mark and drill appropriate climb holes for the solenoids and reverse contactor on the side face of each rectangle.

Step 58: Wire the Drive Circuit

Electrify up the drive circuit A outlined in the wiring plot.

Be steady to used the 2AWG cable for the high current 24V connections.

To figure a generic DC motor wiring diagram from Alltrax, run down this link.

Abuse 59: Attach the Bottom Plate

Attach the bottom drive tour dental plate by placing it on a sheet of cardboard and sliding information technology below the bed.

Erst or s in position, get up it up onto blocks and bolt the front to the underside of the gear box using 7/16-14 x 3/4" bolts.

Steady the back side of meat of the dental plate in place past insert 1/2-13 x 12" bolts down through with, fender washers, the torsion box, atomic number 13 tubes, and finally the plate itself. Finally, lock the bolts in situ with nylon insert daft.

Step 60: Conducting wire the Motors

Wire the colored wire from the reversion contactor to the leftmost terminal on the left motor.

Wire the black ground telegram from the motor controller to the right terminal on the left motor.

Repeat this process for the right efferent.

Step 61: Drive Circuit User interface

Build up the labor racing circuit interface boards every bit outlined in the betrothed schematic. It is wise to use screw terminals for all of the connexion points.

To explicate what is going on, the SPST relay is organism used to turn on and off the motor controller and the SPDT electrical relay is being wont to engage the opposite contactor and shift directions. When the guidance is about to be changed, the SPST relay cuts the power and then the SPDT relay changes centering. This is important to do to stay fresh the circuit from breaking.

The 6A diode and fuse are largely just in that respect to prevent potential dro and/or rife spikes.

The other set of diodes is being used to connect the reverse relay to the lighting pole without crossing wires between forwards and back.

Step 62: The Remaining Circuit

Build the rest of the circuit Eastern Samoa nominative in the schematic to a higher place.

Step 63: Write in code

Okay - so - when working with code it is ideal to use something like Github to support track of revisions. I don't do this. Thus, I unintentionally wrote terminated the near prevailing working version of the encipher. I do cause the last found version, but I am not certain how exhaustive it is. It is likely a little fruity.

Novertheless, since no of you will probable build this matter any which way, and the bed is presently in pieces and not operational, I am just active to post what I have.

I am also sharing test inscribe for manually controlling the motors. If you are looking this envision for interfacing an Arduino to very large motors done an Alltrax motor controller, this code will be more useful to you anyhow.

Last saved version of Robot Bed test code:

/* This example code is in the public domain.    */  //establish throttle pins int leftThrottle = 3;    // LED engaged to digital pin 9 int rightThrottle = 5;    // LED connected to extremity PIN number 9  //establish solenoid pins int leftOn = 7;    // LED associated to digital fall 9 int rightOn = 8;    // LED connected to member pin 9  //establish contactor pins int leftReverse = 9;  int rightReverse = 10;      //The campaign speed sent to the throttle int gospeed = 86;  volatile int foserious = 0;    //FRONT  int FrontLeftSnd = 30;  int FrontLeftRcv = 31;   int FrontCenterSnd = 32;  int FrontCenterRcv = 33;   int FrontRightSnd = 34;  int FrontRightRcv = 35;   //RIGHT SIDE  int Side1LeftSnd = 36;  int Side1LeftRcv = 37;   int Side1CenterSnd = 38;  int Side1CenterRcv = 39;   int Side1RightSnd = 40;  int Side1RightRcv = 41;   //BACK  int BackLeftSnd = 42;  int BackLeftRcv = 43;   int BackCenterSnd = 44;  int BackCenterRcv = 45;   int BackRightSnd = 46;  int BackRightRcv = 47;   //Larboard SIDE  int Side2LeftSnd = 49;  int Side2LeftRcv = 48;   int Side2CenterSnd = 51;  int Side2CenterRcv = 50;   int Side2RightSnd = 53;  int Side2RightRcv = 52;   //array of all of the stimulus and output pin names. Used later to read all of the sensors in a for grummet.  int SensorOutputs[] = {FrontLeftSnd, FrontCenterSnd, FrontRightSnd, Side1LeftSnd, Side1CenterSnd, Side1RightSnd, BackLeftSnd, BackCenterSnd, BackRightSnd, Side2LeftSnd, Side2CenterSnd, Side2RightSnd};  int SensorInputs[] = {FrontLeftRcv, FrontCenterRcv, FrontRightRcv, Side1LeftRcv, Side1CenterRcv, Side1RightRcv, BackLeftRcv, BackCenterRcv, BackRightRcv, Side2LeftRcv, Side2CenterRcv, Side2RightRcv};   int dontgo = 0;   //number of sum up sensors  int SensorCount = 12;   int nothingHappening = 0;   int realCloseLike = 0;   int goingforward = 0;  int goingbackward = 0;  int goingright = 0;  int goingleft = 0;   int backhit = 0;  int fronthit = 0;  int righthit = 0;  int lefthit = 0;   int amountToMove = 1000;   int picked;  emptiness setup()  {        CLI();//full stop interrupts    TCCR1A = 0;// readiness entire TCCR1A register to 0   TCCR1B = 0;// similar for TCCR1B   TCNT1  = 0;//initialize counter value to 0   // set compare match register for 1hz increments   OCR1A = 512;// = (16*10^6) / (1*1024) - 1 (must be <65536)   // switch on Counterterrorist Center musical mode   TCCR1B |= (1 << WGM12);   // Set CS10 and CS12 bits for 1024 prescaler   TCCR1B |= (1 << CS12) | (1 << CS10);     // enable timekeeper compare break   TIMSK1 |= (1 << OCIE1A);    sei();//allow interrupts        Serial.begin(9600);       pinMode(leftOn, Output signal);   pinMode(rightOn, OUTPUT);       pinMode(leftReverse, OUTPUT);   pinMode(rightReverse, OUTPUT);     //Micturate sure the power is off   digitalWrite(leftOn, Low pressure);   digitalWrite(rightOn, Contemptible);   digitalWrite(leftReverse, Low-growing);   digitalWrite(rightReverse, Low-pitched);       //bumper sensor pins    pinMode(18, Stimulation);   pinMode(19, Stimulant);         //Countersink distance sensor output pins   pinMode(FrontLeftSnd, End product); //pin 30   pinMode(FrontCenterSnd, Outturn); //stick 32   pinMode(FrontRightSnd, OUTPUT); // pin 34   pinMode(Side1LeftSnd, OUTPUT); //oarlock 36   pinMode(Side1CenterSnd, OUTPUT); //pin 38   pinMode(Side1RightSnd, Outturn); // stick 40    pinMode(BackLeftSnd, End product); //pin 42   pinMode(BackCenterSnd, OUTPUT); //peg 44   pinMode(BackRightSnd, Outturn); // pin 46   pinMode(Side2LeftSnd, OUTPUT); //pin 49   pinMode(Side2CenterSnd, Production); //trap 51   pinMode(Side2RightSnd, OUTPUT); // peg 53      //Readiness distance sensor input pins   pinMode(FrontLeftRcv, INPUT); //pin 31   pinMode(FrontCenterRcv, Input signal); //pin 33   pinMode(FrontRightRcv, Stimulation); //pin 35   pinMode(Side1LeftRcv, INPUT); //immobilize 37   pinMode(Side1CenterRcv, INPUT); //pin 39   pinMode(Side1RightRcv, Stimulus); //oarlock 41   pinMode(BackLeftRcv, INPUT); //thole 43   pinMode(BackCenterRcv, INPUT); //pin 45   pinMode(BackRightRcv, INPUT); //pin 47   pinMode(Side2LeftRcv, Stimulant); //pin 48   pinMode(Side2CenterRcv, INPUT); //pin 50   pinMode(Side2RightRcv, INPUT); //pin 52           //And wait a moment    delay(3000);  }   void coil()  {       lookAllAround();      moveRobot();   delay(amountToMove);   slowstop();   delay(1500);   }   ISR(TIMER1_COMPA_vect) {   //Interrupt at freq of 1kHz to valu reed switch//generates pulse wafture of frequency 8kHz/2 = 4kHz (takes two cycles for full wave- toggle high then toggle low)   if(lefthit == 0 && righthit == 0 &&adenosine monophosphate; fronthit == 0 && backhit == 0){   if(digitalRead(18) == Adenoidal){     hardstop();     Serial.println(goingbackward);     Serial.println(goingforward);     Serial.println(goingleft);     Serial.println(goingright);          Serial.println("FUCK YEAH!");     if(goingright == 1){       righthit = 1;       goingright = 0;     }     if(goingleft == 1){       lefthit = 1;       goingleft = 0;     }     if(goingbackward == 1){       backhit = 1;       goingbackward = 0;     }     if(goingforward == 1){       fronthit = 1;       goingforward = 0;     }   }       }   if(lefthit == 0 && righthit == 0 &adenosine monophosphate;& fronthit == 0 && backhit == 0){     if(digitalRead(19) == HIGH){     hardstop();     Serial.println("FUCK NO!");     Serial.println(goingbackward);     Serial.println(goingforward);     Serial.println(goingleft);     Serial.println(goingright);          if(goingbackward == 1){       backhit = 1;       goingbackward = 0;     }     if(goingforward == 1){       fronthit = 1;       goingforward = 0;     }    if(goingright == 1){       righthit = 1;       goingright = 0;     }     if(goingleft == 1){       lefthit = 1;       goingleft = 0;     }   }  }        }   void moveRobot(){          //first catch if hit -- if hit patc haunting in any of the directions - auto-pick the other direction    //-- other break up randomly    if(backhit == 1){     amountToMove = 1000;      backhit = 0;     fronthit = 0;     lefthit = 0;     righthit = 0;     picked = 0;   }   other if(fronthit == 1){     amountToMove = 1000;      backhit = 0;     fronthit = 0;     lefthit = 0;     righthit = 0;    picked = 1;   }    else if(lefthit == 1){     amountToMove = 500;      backhit = 0;     fronthit = 0;     lefthit = 0;     righthit = 0;     picked = 2;   }    else if(righthit == 1){     amountToMove = 500;      backhit = 0;     fronthit = 0;     lefthit = 0;     righthit = 0;     picked = 3;   }   else{     picked =  hit-or-miss(3);     Ordered.println("WTF!?");     amountToMove = 1000;   }      switch(picked){      case 0:           goingforward = 1;        goingbackward = 0;        goingright = 0;        goingleft = 0;        forwards();        Sequent.println("buy the farm forwards");                break;      slip 1:         goingforward = 0;        goingbackward = 1;        goingright = 0;        goingleft = 0;               backwards();        Nonparallel.println("return");         break;      case 2:           goingforward = 0;        goingbackward = 0;        goingright = 1;        goingleft = 0;          reactionist();        Serial.println("go right");         break;      case 3:            goingforward = 0;        goingbackward = 0;        goingright = 0;        goingleft = 1;        left();        Serial.println("move out left");         break;      }            delay(1);        // delay in between reads for stability  }   void forwards(){       //activate the inverse contactor   digitalWrite(leftReverse, HIGH);   wait(50);   digitalWrite(rightReverse, HIGH);      hold up(100);      //activate the solenoids   digitalWrite(leftOn, HIGH);   digitalWrite(rightOn, HIGH);      //take a breath   stay(500);    //absorb the bound   analogWrite(rightThrottle, gospeed);     analogWrite(leftThrottle, gospeed);     }   quash backwards(){           //activate the solenoids   digitalWrite(leftOn, Heights);   digitalWrite(rightOn, Richly);      //take a breath   delay(500);      // engage the throttle   analogWrite(rightThrottle, gospeed);     analogWrite(leftThrottle, gospeed);       }     void right(){         if(dontgo == 0){     //activate the solenoids     digitalWrite(leftOn, HIGH);     digitalWrite(rightOn, Ill-smelling);        //activate the annul contactor     digitalWrite(rightReverse, HIGH);        //take a breath     time lag(500);      //engage the throttle     analogWrite(rightThrottle, gospeed);       analogWrite(leftThrottle, gospeed);    }      //reset the variable   dontgo = 0;  }   void left(){         if(dontgo == 0){       //activate the solenoids     digitalWrite(leftOn, HIGH);     digitalWrite(rightOn, HIGH);        //activate the reverse contactor     digitalWrite(leftReverse, HIGH);        //take a breather     delay(500);      //absorb the throttle     analogWrite(rightThrottle, gospeed);       analogWrite(leftThrottle, gospeed);    }      //reset the variable   dontgo = 0;    }    void slowstop() {      for(int fadeValue = gospeed ; fadeValue >= 0; fadeValue -=5) {      // sets the time value (range from 0 to 255):     analogWrite(rightThrottle, fadeValue);          analogWrite(leftThrottle, fadeValue);                  // wait for 30 milliseconds to go out the dimming effect         delay(500);                               }        digitalWrite(leftOn, LOW);   digitalWrite(rightOn, LOW);   digitalWrite(leftReverse, Low-level);   digitalWrite(rightReverse, Low-growing);    int goingforward = 0;   int goingbackward = 0;   int goingright = 0;   int goingleft = 0;    delay(2000);   lookAllAround();   delay(1000);  }  void hardstop() {      for(int fadeValue = gospeed ; fadeValue >= 0; fadeValue -=5) {      // sets the value (range from 0 to 255):     analogWrite(rightThrottle, fadeValue);          analogWrite(leftThrottle, fadeValue);                  // wait for 30 milliseconds to see the dimming effect         altDelay(50);                               }        digitalWrite(leftOn, LOW);   digitalWrite(rightOn, LOW);   digitalWrite(leftReverse, LOW);   digitalWrite(rightReverse, LOW); }  void altDelay(int x)   {   for(unsigned int i=0; i<=x; i++)      {     delayMicroseconds(1000);   } }   void lookAllAround(){    long continuance, inches, cm;      for (int thisPin = 0; thisPin < 1; thisPin++) {       digitalWrite(SensorOutputs[thisPin], LOW);     delayMicroseconds(2);     digitalWrite(SensorOutputs[thisPin], HIGH);     delayMicroseconds(12);     digitalWrite(SensorOutputs[thisPin], Nether);           duration = pulseIn(SensorInputs[thisPin], HIGH);     digitalWrite(SensorOutputs[thisPin], LOW);      // convert the prison term into a outstrip     inches = microsecondsToInches(duration);      Serial.photographic print(SensorOutputs[thisPin]);      Serial.print(": ");      Serial.print(inches);      Serial.println("in, ");  //    //check and check again //    if(inches > 10 && inches < 25){ //        realCloseLike = 0; //        for(int checkagain = 0; checkagain < 3; checkagain++) { //           delay(100); //           digitalWrite(SensorOutputs[thisPin], LOW); //           delayMicroseconds(2); //           digitalWrite(SensorOutputs[thisPin], HIGH); //           delayMicroseconds(12); //           digitalWrite(SensorOutputs[thisPin], LOW);  //            //           duration = pulseIn(SensorInputs[thisPin], Graduate); //           inches = microsecondsToInches(continuance); //           digitalWrite(SensorOutputs[thisPin], LOW); //            //           delay(100); //            //           if(inches > 10 && inches < 25){ //              //                 Serial.print(SensorOutputs[thisPin]);  //                 Serial publication.print(": ");  //                 Serial.photographic print(inches);  //                 Serial.println("in, "); //                  //                 realCloseLike = realCloseLike + 1; //                  //                 if(realCloseLike > 2){ //                   dontgo = 1; //                 }          //               } //             } //           }                //Takes more or less 1/2 second to mark all of the sensors @ 50uS     delay(100);        }   }    seven-day microsecondsToInches(prospicient microseconds) {   // According to Parallax's datasheet for the PING))), in that location are   // 73.746 microseconds per column inch (i.e. stable travels at 1130 feet per   // second).  This gives the distance travelled by the ping, outgoing   // and revert, so we divide by 2 to get the distance of the obstacle.   // Determine: <a href="http://www.parallax.com/decilitre/docs/poke at/Air Combat Command/28015-Pink-v1.3.pdf"> <a href="http://www.parallax.com/dl/docs/prod/Air Combat Command/28015-PI...</a"> hypertext transfer protocol://www.parallax.com/dl/docs/prodding/acc/28015-PI...</a>>   return microseconds / 74 / 2; }

Motorial control test inscribe example:

              /* This example computer code is in the public domain.    */  //plant throttle pins int leftThrottle = 3;    // LED connected to digital pin 9 int rightThrottle = 5;    // LED connected to digital pin 9  //ground solenoid pins int leftOn = 7;    // Light-emitting diode connected to digital pin 9 int rightOn = 8;    // LED engaged to whole number PIN number 9  //found contactor pins int leftReverse = 9;  int rightReverse = 10;      //The drive speed sent to the strangle int gospeed = 82;   int nothingHappening = 0;   int realCloseLike = 0;   int goingforward = 0;  int goingbackward = 0;  int goingright = 0;  int goingleft = 0;   int backhit = 0;  int fronthit = 0;  int righthit = 0;  int lefthit = 0;   int amountToMove = 1000;   int timeToWait = 30000;   int picked;  void setup()  {        cli();//stop interrupts    TCCR1A = 0;// set entire TCCR1A register to 0   TCCR1B = 0;// same for TCCR1B   TCNT1  = 0;//initialize counter treasure to 0   // set compare match register for 1hz increments   OCR1A = 512;// = (16*10^6) / (1*1024) - 1 (must be <65536)   // turn on CTC mode   TCCR1B |= (1 << WGM12);   // Set CS10 and CS12 bits for 1024 prescaler   TCCR1B |= (1 << CS12) | (1 << CS10);     // enable timekeeper comparison interrupt   TIMSK1 |= (1 << OCIE1A);    sei();//allow interrupts        Music.start(9600);       pinMode(leftOn, OUTPUT);   pinMode(rightOn, OUTPUT);       pinMode(leftReverse, OUTPUT);   pinMode(rightReverse, OUTPUT);     //Throw sure the power is off   digitalWrite(leftOn, LOW);   digitalWrite(rightOn, LOW);   digitalWrite(leftReverse, LOW);   digitalWrite(rightReverse, Soft);       //bumper sensor pins    pinMode(18, INPUT);   pinMode(19, INPUT);              //And wait a moment    stay(3000);  }   void loop()  {        left();   delay(amountToMove);   slowstop();   check(timeToWait);    backwards();   delay(amountToMove);   slowstop();   delay(timeToWait);      forwards();   postponement(amountToMove);   slowstop();   delay(timeToWait);      right();   delay(amountToMove);   slowstop();   retard(timeToWait);      ///      right();   delay(amountToMove);   slowstop();   stay(timeToWait);      forwards();   delay(amountToMove);   slowstop();   delay(timeToWait);      backwards();   delay(amountToMove);   slowstop();   delay(timeToWait);      left();   delay(amountToMove);   slowstop();   delay(timeToWait);     ///    forwards();   delay(amountToMove);   slowstop();   delay(timeToWait);      back();   delay(amountToMove);   slowstop();   delay(timeToWait);      forwards();   delay(amountToMove);   slowstop();   delay(timeToWait);      backward();   delay(amountToMove);   slowstop();   delay(timeToWait);   }   ISR(TIMER1_COMPA_vect) {   //Break up at freq of 1kHz to measure beating-reed instrument switch//generates pulse wave of frequency 8kHz/2 = 4kHz (takes deuce cycles for full wave- toggle high then toggle low)   if(lefthit == 0 &&adenosine monophosphate; righthit == 0 &A;& fronthit == 0 && backhit == 0){   if(digitalRead(18) == HIGH){     hardstop();          Serial.println(goingbackward);     Serial.println(goingforward);     Series.println(goingleft);     Serial.println(goingright);     Ordering.println("FUCK Yea!");          if(goingright == 1){       righthit = 1;       goingright = 0;     }     if(goingleft == 1){       lefthit = 1;       goingleft = 0;     }     if(goingbackward == 1){       backhit = 1;       goingbackward = 0;     }     if(goingforward == 1){       fronthit = 1;       goingforward = 0;     }   }       }   if(lefthit == 0 && righthit == 0 && fronthit == 0 && backhit == 0){     if(digitalRead(19) == HIGH){     hardstop();      Serial.println(goingbackward);     Serial.println(goingforward);     Serial.println(goingleft);     Serial.println(goingright);     Serial.println("FUCK No!");          if(goingbackward == 1){       backhit = 1;       goingbackward = 0;     }     if(goingforward == 1){       fronthit = 1;       goingforward = 0;     }    if(goingright == 1){       righthit = 1;       goingright = 0;     }     if(goingleft == 1){       lefthit = 1;       goingleft = 0;     }   }  }        }   void moveRobot(){          //first see if hit -- if striking while squirming in whatsoever of the directions - auto-weft the other direction    //-- other pick over randomly    if(backhit == 1){     amountToMove = 1000;      backhit = 0;     fronthit = 0;     lefthit = 0;     righthit = 0;     picked = 0;   }   other if(fronthit == 1){     amountToMove = 1000;      backhit = 0;     fronthit = 0;     lefthit = 0;     righthit = 0;    picked = 1;   }    else if(lefthit == 1){     amountToMove = 500;      backhit = 0;     fronthit = 0;     lefthit = 0;     righthit = 0;     picked = 2;   }    else if(righthit == 1){     amountToMove = 500;      backhit = 0;     fronthit = 0;     lefthit = 0;     righthit = 0;     picked = 3;   }   else{     picked =  unselected(3);     Music.println("WTF!?");     amountToMove = 1000;   }      switch(picked){      sheath 0:           goingforward = 1;        goingbackward = 0;        goingright = 0;        goingleft = 0;        forwards();        Serial.println("go forwards");                break;      case 1:         goingforward = 0;        goingbackward = 1;        goingright = 0;        goingleft = 0;               backward();        Serial.println("depart back");         violate;      suit 2:           goingforward = 0;        goingbackward = 0;        goingright = 1;        goingleft = 0;          right();        Serial.println("go right");         break;      example 3:            goingforward = 0;        goingbackward = 0;        goingright = 0;        goingleft = 1;        left();        Serial publication.println("go left");         give;      }            delay(1);        // delay in between reads for stability  }   void forwards(){       //trigger the reverse contactor   digitalWrite(leftReverse, HIGH);   delay(50);   digitalWrite(rightReverse, Tenor);      delay(100);      //activate the solenoids   digitalWrite(leftOn, HIGH);   digitalWrite(rightOn, HIGH);      //undergo a breath   delay(500);    //engage the restrain   analogWrite(rightThrottle, gospeed);     analogWrite(leftThrottle, gospeed);   }   void backwards(){           //activate the solenoids   digitalWrite(leftOn, HIGH);   digitalWrite(rightOn, HIGH);      //take a breath   delay(500);      // lock the throttle   analogWrite(rightThrottle, gospeed);     analogWrite(leftThrottle, gospeed);       }     void right(){           //activate the solenoids     digitalWrite(leftOn, In flood);     digitalWrite(rightOn, Altissimo);        //set off the reverse contactor     digitalWrite(rightReverse, HIGH);        //breathe out     wait(500);      //engage the throttle     analogWrite(rightThrottle, gospeed);       analogWrite(leftThrottle, gospeed);    }   void left(){           //activate the solenoids     digitalWrite(leftOn, High schoo);     digitalWrite(rightOn, HIGH);        //activate the reverse contactor     digitalWrite(leftReverse, HIGH);        //breathe     delay(500);      //take the throttle     analogWrite(rightThrottle, gospeed);       analogWrite(leftThrottle, gospeed);      }    quash slowstop() {      for(int fadeValue = gospeed ; fadeValue >= 0; fadeValue -=5) {      // sets the note value (range from 0 to 255):     analogWrite(rightThrottle, fadeValue);          analogWrite(leftThrottle, fadeValue);                  // waitress for 30 milliseconds to see the dimming effect         delay(500);                               }        digitalWrite(leftOn, LOW);   digitalWrite(rightOn, Under);   digitalWrite(leftReverse, LOW);   digitalWrite(rightReverse, LOW);    int goingforward = 0;   int goingbackward = 0;   int goingright = 0;   int goingleft = 0;  }  void hardstop() {      for(int fadeValue = gospeed ; fadeValue >= 0; fadeValue -=5) {      // sets the value (range from 0 to 255):     analogWrite(rightThrottle, fadeValue);          analogWrite(leftThrottle, fadeValue);                  // wait for 30 milliseconds to see the dimming effectuate         altDelay(50);                               }        digitalWrite(leftOn, LOW);   digitalWrite(rightOn, LOW);   digitalWrite(leftReverse, LOW);   digitalWrite(rightReverse, LOW); }  void altDelay(int x)   {   for(unsigned int i=0; i<=x; i++)      {     delayMicroseconds(1000);   } }            

Step 64: Mount the Electronics

Cut an electronics climb up tabu of 1/4" clear acrylic fiber using the attached templet.

Mount all of the circuit boards to the acrylic plateful using 1/4" standoffs and M3 bolts.

Step 65: Testing!

Plug everything in an test all of the circuitry before mounting it underneath the get laid.

I cannot stress how important it is to make a point evrything industrial plant in front really installing it. This will make life much easier.

Step 66: Install the Circuit Board

Once sure as shooting everything works, climb on the circuit board to the underside of the bed using 1/4" inner diameter by 2" acrylic tubes and 1/4-20 x 4" nuts, bolts and washers.

Abuse 67: Plug in the Sensors

Fire hydrant all of the sensors into their respective sockets on the circuit (if you have not done so already).

At length, clean up all of the cables using energy ties to keep things fastidious and tidy.

Step 68: Strap in the Batteries

Strap the batteries to the battery plate victimisation ratchet straps. Pee certain that the rachet up mechanisms are along the sides of the batteries and not the tops (of it South Korean won't mount to the underside of the hit the hay).

Neatly coil the remaining strap once done.

Step 69: Bolt the Batteries

Bolting the batteries to the underside of the bed is a pain in the neck since each set weighs well-nig 140 pounds.

That said, it is fairly easy if you have a pallet knave. You can just roll them under and lift them a couple of inches off the ground until they are high enough to pass bolts through.

Without that, I found that putt the batteries on cardinal 8' 2x4s and slow propping dormie apiece end until you catch the bolt of lightning also works.

Insert 1/2-13 x 10" bolts depressed through a wing washer, the wooden crookednes box frame, a 7-1/2" aluminum spacing tube and last the battery mounting plate. Firmly lock the bolt in place with a nylon insert nut.

Step 70: Charger Box

Plug both of the battery chargers into the battery charger junction box.

When they start spouting low, plug the battery charger junction boxful into the paries.

Step 71: Put the Mattress On

Lift the mattress backrest onto the bedframe.

Step 72: Make the Bed

When you make the get it on, be sure to tuck the sheets under the mattress. You would not want to leave them dangling and risk having them stupefy sucked into the wheels. That could be stinking.

Footstep 73: Turn It On

Flip the large power tack to its side to engage the bed.

Step 74: Enjoy

Let your bed take you for a ride and urinate new friends.

Did you find this useful, fun, operating theatre entertaining?
Come after @madeineuphoria to see my latest projects.

Be the First to Share

Recommendations