Non-elegant programming solution

Here's the problem: I have a bot that uses motor B and an arm to lift a heavy item. The motor is powerful enough to lift the item. After the item is lifted, the bot program continues on its way (maybe moving forward or backwards or moving into a LOOP block with a sensor trigger.) The problem occurs after motor B completes its lifting motion. As soon as the program moves forward, the weight of the heavy object causes motor B to spin in the opposite direction (gravity, not powered) and the arm (and object) slowly lowers (sometimes quickly).

So my next solution was to put motor B's action in parallel with the rest of the graphical code. I created a branch off of the main one and put motor B there... but here's the next problem. I can either program motor B to spin (rotation or degrees) in an Unlimited fashion, BUT I must have something for motor B to lift the item against and then when it hits, keep applying upward force (motor B still running, but the motor isn't actually spinning). This might work, but I actually need the item held parallel to the floor and not being pushed against something to hold it... once again, doing it this way works until motor B finishes its rotation and then the heavy object lowers again to the ground.

My solution isn't elegant, but I figured it was worth sharing in case someone else encounters this problem. What I did was configure Motor B to spin 90 degrees (.25 rotations) and at that point the object is being held, parallel to the ground. I then inserted a LOOP block - inside the loop block is MOVE block for Motor B to spin down .1 rotation and then another MOVE block that has Motor B spin up .1 rotation... I set the LOOP to loop Forever, and it worked... the bot holds the object parallel to the floor... the .1 rotation up and down motion isn't even noticeable... but the solution is that the motor is quickly spinning up and down, up and down and never powers down for the object to sink down again.

Anyone have a better solution? I tried applying a MOVE block that stops Motor B (braking) after the initial Motor B block lifts the object, but I didn't think it would work... and it didn't. What is really needed is for the MOVE blocks to have a check box that says "After motion is completed, lock the motor" or something similar to keep the motor from spinning.

If anyone else has any ideas, please post them.


Anonymous said…
I think the only other choice would be to make your own mechanical lock with other pieces. But that would a thousand times harder than your idea.
Anonymous said…
This problem points out both a limitation of the NXT servo gearmotors as well as a possible opportunity for either LEGO engineers or others:

The workable range of power of the motors is extremely limited. If you want more power, you must design the system to use gear or lever reduction. Even so, the problem is that (as with many dc gearmotor systems), the output torque is not only limited, but constant. Lower load, faster speed, higher load, lower speed, until stall.

What we need is a current control option, which will specify not a speed, but a variable torque based on load. Using this, you could specify maximum torque to be applied to a variable load at it's heaviest point, then when it lowers, the torque is reduced so that the motor does not overspeed.

Many DC (as well as AC) servo systems can do this. I don't know what it would take to get it into the NXT, but it sure would be nice.
Anonymous said…
If you don't need too much speed, the worm gear is a solution, as it can't be driven by the gear it leads. But you get lots of down gearing and quite a bit of friction...
Anonymous said…
It sounds like the motors are not able to supply enough static torque. The best solution in that case is to add some reduction gears.

I'm not sure if you have ever played with some of the hold lego motors but they could produce almost negligible torque and would stall quite frequently. The solution was some gear reduction, it slowed down the output rotation but the torque goes up proportionately.

You can experimentaly determine the amount of reduction needed for your application. Start with a small gear on the motor shaft and have it spin the biggest gear you have and then alternate big and small.
Anonymous said…
Isn't it possible to read the location of the servo off the servo itself. If so could you setup your parallel program to pause based on the location of the servo and if it moves down, then move it back up?
Sorry, Anonymous... you'll need to be more specific as I'm not understanding exactly what your solution will look like.

I don't want the arm to move at all once it has achieved it's parallel position (to the floor).

By using very small incremental up-and-down movements with the LOOP-MOVE block combo, I can keep the arm at exactly the same point.

As for the other suggestions - gearing is definitely an option. Using the worm gear is something I'll look at, but the design of my bot doesn't really lend itself to using a gear for movement of the lifting mechanism... wish I could be more specific, but I'm not able to share this bot's design at the moment. But I'm still going to try it and see what it looks like.

Thanks, all.

Drew Stevenson said…
I had the same Idea as Annonymous so maybe I can explain it.
The NXT servos can note their own location to I think its 1 degree. Instead of moving up and down 1 degree forever (that'd be a bugger on battery life) why not power up that amount then let gravity have it only for that 1 degree it would take to notice. (gears would add more torque and a one degree motor change could be 1/24th (or less) of 1 degree. This power up, gravity fall cycle would conserve battery life. It might create a bit of shuddering but I imagine no more than a similarly powered cycle.
Personally I would choose Pneumatics for static heavy lifting. They are great for large loads from A to B position. They do require a bit of infrastructure but the huge number of studded pneumatics designs would slide seamlessly into an unstudded frame. Or you could probably redesign an unstudded framework. Unstudded air power systems might be more easily decentrialized than the old stud designs that needed to be grouped for strength.

What about using the break comand. Cycle forever a motor block that gives full power for 0 seconds and ends with a break. (perhaps a motor stop comand cycled forever).

Does the object need to decend again? if not an elastic band powered arm could be triggered into a support position after the lift.

What about a ratchet. Limit motion to one direction. Ratchets could be disengaged by a manual trigger (a post a the unloading zone could hit a beam connected to the ratchet and then allow for the drop but only at the desitination.)

Alternatively - use beams to take the motor motion and make it a pulling motion (which could then act on a bent beam to generate rotation elsewhere). using two beams pivoting you could make them "lock-up" fairly easily. But better still is to make the "end positon" so that the pin which is on the outside holes of the orange motor (or a 2xpulley) will be on the far side or near side of the rotation. Thus any pulling forces will pull through the center of rotation and NOT generate rotation. (above or bellow these points forces create spin. But right on these points no rotation can be generated from outside, leaving the servo free to act. (same benifits as a worm gear really but maybe more applicable to some designs.)

One final idea (for now):
Counter Weights. If the motor can move the weight then simply use a similarly weighted or leveraged counter weight with the motor as pivot. The motor can move under unloaded conditions (but will drift if no load is aquired to balance.) to pick up the other object. The weights then balance and it becomes easy for friction to mainatin the balance. You might not even need an identical weight. Just enough to get you into the friction zone (dont forget leverage - longer distance from pivot creates greater effect from smaller weight).
If you need lego weights they are avaialble from education lego but I find that the different battery packs work very well. My favorite esp. for studdless building is an only NXT that I got stuck with on a bad "as is" ebay order. ("seems to work but sold as is") Yeah now it works as a paper weight and counter wieght (and the power connectors are great for rewiring with gator clips).

Hope these ideas help SOMEONE out there.

PS ok 1 more - what about wheels on the grabber mechanism that bear weight when object is parrallel but when lowered or being picked up would squish a bit (maybe spring load the wheel support beam)so that they could allow movement and get themselves out of the way.

Drew "He of many ideas" is now hanging his idea-shotgun at bNXT with Filip, come say Hi.

Some excellent suggestions... I still don't see how my running the motors up-down in small increments will kill the batteries any more than letting gravity take control for a short time, then powering up again... but maybe I'm still not envisioning what you are seeing in your mind...

The robot's design is limited to what comes ONLY in the retail kit, so pneumatics are out for now... and the design also limits me to the simple lifting arm... but your idea of converting that to pulling energy is an interesting one...

I wish I could just post a silly picture of this thing for everyone to look at... but alas, my hands are tied for now.

Battery power really isn't an issue for the up-down motion of my motors, though - it only does this for about 10 seconds (time needed for the bot to reverse direction and return object).

Still, I hope everyone is taking note of all of these great suggestions for their own designs.

Anonymous said…
Something about the ratchet (or however you spell it) -

Let's say you hook up two motors to a single port, port A. (Not possible as of yet that I know of.)

The first motor attaches to the port in a normal fashion. A ratchet allows this motor to lift the arm, but not lower it.

The second motor can be an old RCX motor which is attached to the same port, but runs through one or two of the small breadboards (sold at first. Using the breadboards, you could make a curcuit that links the motor to the port in a normal way exept that a diode only allows the motor to spin in one direction (for example if you told the NXT to spin the motor to the left, it would work, but if you told it to spin to the right, it would not work because of the diode).

This means that when you tell the NXT brick to spin the motors on Port A to the right, the first motor will spin just fine, lifting the arm, while the second motor remains stationary because of the diode.

However, when you tell the NXT to spin the motors on Port A to the left, well several things would happen.
1. At first the first motor which is attached to the arm will not work because of the ratchet.
2. The second motor WILL spin. Now, this second motor is attached to the ratchet, and lifts it.
3. Now with the ratchet out of the way, the first motor can lower the arm.
4. The second motor lifts the ratchet until it hits a beam and is unable to lift it any more; however, it is still applying force to the ratchet so it doesn't fall back down.
5. Now your arm is down, and everything is fine. When you tell the motors to lift the arm back up, everything will reset; the first motor lifts the arm, the second motor stops working, and the ratchet falls back into place because of its weight. Even if you just tell the motors to stop, instead of lift the arm back up, everything should work; the ratchet, if it is heavy enough, will fall back in place, and the arm will stay stationary.

Hmmm. . . seems kind of far-fetched, and clumsy. But I think it would work, the only problem is putting all of this into your design.

Oh, and the other problem is attaching more than one motor to a single port.

Gordon B said…
If you use the motor block and set duration=0 degrees and check wait for completion and brake then follow it with an infinite loop then it locks the motor until the program is ended.
Anonymous said…
Hmmm. . . Jim's comment wasn't visible when I wrote mine a second ago.

My idea is most likely not possible with just the pieces in the kit.

Nice, Gordon... better.

I need to test it (unless you already did)... but it's excellent.

Drew Stevenson said…
Gordon, Thats a more elequent way of what I suggested: "What about using the break comand. Cycle forever a motor block that gives full power for 0 seconds and ends with a break. (perhaps a motor stop comand cycled forever)." I had not tested it.
Have you tested any variations of "Do alot of Nothing looped Forever".
I'd be excited to hear which variations of this theme work and how some of them might have "twists" (like use more power, hold more wieght, etc)

As for Power consumption if applying power to the motor uses up power then having a cycle where gravity is the only active force (friction counters it a bit) then you save power as compared to a power in both directions. My math says Power up AND down is more expensive power wise than Power up Gravity down as a loop.
But your right 10 sec is not bad.

Working with in the kit is great for everyone. It can be very frustrating for those of us with access to more, but remember that this might be some peoples firts forey into TECHNIC style parts. They need ideas and inspiration. Its easy to build with unlimited stuff but hard to limit yourself.

What about a picture of PART of the robot - a Module.
Gordon B said…
Ok, I tested this a bit more. It seems that a Move or Motor block works and you can just set it to Stop. As long as the program is still running the motor works to keep the rotation count unchanged (ie holds the motor in place).

I found this out earlier this week when I was trying out the idea of using a motor as a remote controller (as others have done). I wanted my control to automatically recenter itself if let go. Putting the motor on Stop does that but at full power which makes the controller too hard to move. I tried moving 0 degrees rotation with Wait and Brake at various power levels but the power level had no effect (even at 0) the motor still worked to hold the current position using its full strength.

I finally got something to sort of work but it had an oscillation that would keep moving slowly back and forth a little. I woiuld like comments on the program.

Is there a way to post an image to this blog?

I tried what you described, but the stop on the MOVE block did work for a second or so, but as soon as the next program block executes, power to motor B is turned off and gravity slowly pulls the arm down.

Gordon B said…
Hmmm ... what is the next programming block that does this? I just tried it now with a following move on a different motor, a sound block, and a wait block. The motor was still locked until I stopped the program.
I'll upload the old .rbt file I was using... I'll try to get it uploaded this evening.

Drew Stevenson said…
What about having the STOP motor block on a different branch linked to a variable on/off comand. that way the branch does not have to have a following block.

As for the remote - what about a code that basicly says: "If rotation not 0 turn on motor with power 10% untill rotation =0". Basicly this could be a Variable based on rotation sensor and a logic block connected to a motor block which may need directional control based on Plus/Minus values. This is on my list of things to test.
Does a power in put that is negative create a reverse or does it become positive or get ignored. I did a program I havent hada chance to test and was not sure if I should put a code in that created a positive or negative motor direction and then absolute valued the power. Was thsi wasted code? So much to test and so little time (and so few NXT's... Education please Ship.)

PICTURES: if you have webspace or a picture posting service post there and then just HTTP copy and paste the link. Thats easy (I dont thing Blog comments allow pics - but I dont know.)

Please email me...

Anonymous said…
I think its better if you should play with some of the hold lego motors; I think they might produce the desired result....

Popular Posts