Main Site Documentation

RE: LoadCape and Trying/Seth


#41

Hello Dave,

No issue. I got some software up and running for the motors. I have been messing around w/ a set of software that is supposed to run both motors but the silly software is giving me trouble.

It is almost like I am trying to fit a cube in a cylinder right now. Yea, you are right. I do not have extreme practice w/ wiring and electronics.

https://github.com/silver2row/loadcape is what I have been working on so far. If you get time to look it over, that would be nice. If not, that is okay too.

Seth

P.S. I have two classes but I may need to add an additional one or take one away to use a wrapper instead. I am just not sure right now.


#42

ok, so here’s how I would troubleshoot the code you presented. Note, I’ve got virtually no idea about Python :slight_smile:

I would get things working in a single class for a single motor.
Car(leftMotor=BrushedDC(m1=“P9_42”)
Prove you can make one wheel do all your primitives - forward back etc
Now, prove the other one works.
Car(leftMotor=BrushedDC(m1=“P9_41”)
(note the change of GPIO for this one)
Prove you can make one wheel do all your primitives - forward back etc

So now you know your code works - it can independently control two different wheels.

Then you need to think about how you combine this - obviously using class structures makes sense, right? edit: I changed this for clarity. So I’d potentially change your current “BrushedDC” class to be “Wheel”, and it should have only primitives such as forward/back/stop. Then your “Car” class needs to have two “Wheel” objects, like you started to do, one left and one right, and introduces concepts like pivot & turn as combinations of primitives where you act on only one wheel or both, in different combinations.

One other thing I think I would change is how you treat the “wait” parameter - without knowing what you think your behaviour is in some detail, this might be an idea to look at. I consider a primitive like “forward” for a duration to be “start”, a “wait”, then a “stop”. Same with back, it’s drive/wait/stop. If your intent in putting waits at the end of each definition like the one below was to have that define the length of time that the motor drove for, then you’re relying on the next step to stop what you were doing, which it may not do - and I notice you have added stop() to the start of a few primitives - that’s actually in my view a bandaid that is more confusing.
def reverse(self, wait=0):
self.leftMotor.reverse()
time.sleep(wait)
# self.leftMotor.stop() # missing
Think about two forward steps:
myCar.forward(5)
myCar.forward(5)
myCar.stop(2)

This calls what I’ll term wheel.Forward, which does a stop then turns on, then waits for 5, then the next call invokes and it calls stop, turns on, waits 5, then the final statement calls stop. While this sequence may seem to generate reasonably close to the correct sequence, it’d be better in my view for Car.Forward to be Wheel.Forward() + wait + stop. Then all you have to do is call Car.Forward(5) twice.


#43

Hello Brett,

Okay…I read what you posted. I do not know when you viewed my software but I am thinking very recently. I will take into account that starting is easiest to call in the software once wait and stop have been invoked.

Seth

P.S. I will also test both motors, i.e. one at a time until I can get both working simultaneously. I think you got what I was gearing towards in the software that I updated recently. I can make the motors move now, which is better than one, in one amount of software but they are not working in sync like I am going to finally make them work.


#44

I reviewed the GitHub repo some time between when you posted the link to it and when I replied. I had the .py file open when Io was replying.

Yes, I get what you were trying to do in your code. Since you were brief in describing what you were seeing in code, I helped how I could - to help you address the discrepancies in how you treat directions than anything.

I’ve had some more thoughts about where you should be controlling the stop as well - because some actions want to be performed at the same time (eg drive both wheels) you need to have two different calls. Wheel.Forward() and Wheel.Forward(time). When there is no time, it just runs until it’s commanded to stop.

If Python classes are like other language classes, you should have no problem creating two objects using the same class - so your CAR class would have a LeftWheel = wheel(leftGPIO) and RightWheel = wheel(rightGPIO).

From there, your car.forward() will do something like:
LeftWheel.forward()
RightWheel.forward()
sleep(waittime)
LeftWheel.stop()
RightWheel.stop()

Your car.turnLeft() might do:
LeftWheel.forward()
RightWheel.reverse()
sleep(waittime)
LeftWheel.stop()
RightWheel.stop()

hope that helps


#45

Hello Brett,

Seth here. Good idea! I should try to control both motors as one at times. “Almost like a transaxle w/ brakes.”

I will test out your idea(s) soon. Python is similar to other languages in way of classes (I think). I am by far a pro. in this field as of now. I just tinker w/ items until I can use them and address concerns from others w/in specific categories of that item.

Anyway…

I will test it out soon.

Seth

P.S. I will reply and let you know exactly if I altered the configuration to better suit this “transaxle” idea w/ two motors.


#46

Hello Again,

I am using this software now to test two motors at different times: https://github.com/silver2row/loadcape/blob/master/SinkOneII.py My def functions should be reusable, right.

Okay…

So…I reuse them at the end but inevitably, this is not what I need. I plan to do something like this w/ the software in the end: https://github.com/silver2row/motocape/blob/master/MotoCape.py. Lines 24 - 56 is what I am describing w/ the imports of my choosing.

Although that software cannot move backwards, someone on Freenode at #beagle showed me a way to make a wrapper w/ classes.

Okay…back to the subject at hand. I am going to make a separate set of software w/ what I believe you are telling me is a good idea. I agree but I need to produce this effect to show you in case I am incorrect. I hope that makes sense.

I will turn the software into what I think you are telling me to do (I know these are just your recommendations on ideas). Do not worry. I do not have to base my entire ideals around what you are saying so I can complain later.

Brb. Off to make this gibberish a reality.

Seth

P.S. Here is that bunch of my gibberish into software: https://github.com/silver2row/loadcape/blob/master/SinkerOne.py. I hope this will provide how incorrect I am at the moment. I tried to understand. I will revisit your ideas soon to make corrections.


#47

all your code is unclear to me what you’re trying to achieve. There’s PWM scattered in one of them (for what?) and it’s not clear what you’re focussing on or how you’re “developing” this.

Start with a single file, that represents a single intent, and focus…

As I’ve shown you, you want to have “primitives” that don’t do a wait. You’ve not considered that. in your last file, SinkerOne.py, you are somewhat there. But some of your code is weird.

Left.forward(5)
Right.forward(5)

So this will start the left wheel, and wait for a count of 5. So in that time, the vehicle will have slewed one way (assuming the right wheel won’t freewheel). Then the right wheel kicks in, and the code waits for a count of 5. The vehicle will essentially drive straight forward (but not the way it was faced when you started). And then the motors are still left running.

Left.stop(5)
Right.stop(5)

So now you stop the left wheel, and wait for another count of 5. In this time the right wheel is still driving, and so it’ll straighten the vehicle to approximately the way it was facing originally, and then it’ll stop the right wheel (it’s now doing nothing) and then you make it wait 5 again.

Left.reverse(5)
Right.reverse(5)

Now you do the whole thing in reverse, slew one way, wait 5, start the other motor, wait 5…

Left.stop()
Right.stop()

And now you stop them both instantly. So at this point, the vehicle is not pointing the way it was originally.

As you can see, these will make a vehicle do stuff - but honestly ordinarily what you want the “higher level” control to do is to direct the vehicle in small iterative steps, not turn it on, wait 5, and hope you get what you want… you really need to distil your primitives even more. Think logically - you’ve done well on your “motor” object, that is all it can really do, but when you start talking about a “wheel”, you have some things that just don’t make logical sense in their own object:

def leftTurnForward(self, wait=0):

self.leftMotor.stop()
time.sleep(wait)

What does that mean?? It just stops the wheel and then sleeps - pointless isn’t it?

def rightTurnForward(self, wait=0):

self.LeftMotor.forward()
time.sleep(wait)

Same here, it’s not a meaningful construct of other functions of a motor.

These are relying on the fact that the other constructs are operating in some way - where what you really want to do is to make them do their own thing and not assume something else is going on.


#48

Hello Brett,

Seth here. Thank you for the clarification. I get what you are saying. Why would a motor stop and wait while the stoppage time is ongoing already? Understood.

Oh and that bunch of software produced is from many related books and articles, some help from Freenode people, and a few additions from me. The /silver2row/motocape/ stuff is what I came up w/ for the MotorCape from GHI and BeagleBoard.org.

I will try to make more sense in the /silver2row/loadcape/ software and report back. Who knows? You may teach me more than I expected on relationships b/t motors and software.

Seth

P.S. Give me about a week so I can come up w/ more ideas on the subject at hand. Oh and I know you are not relying on my return of service but this forum is nice!