Chief Delphi

Chief Delphi (http://www.chiefdelphi.com/forums/index.php)
-   Java (http://www.chiefdelphi.com/forums/forumdisplay.php?f=184)
-   -   How to Program Mecanum (http://www.chiefdelphi.com/forums/showthread.php?t=133904)

cstelter 05-02-2015 12:03

Re: How to Program Mecanum
 
I think you need to add Scheduler.run() in TeleopPerodic()

Edit: Never go off memory-- it should be

Code:

    public void teleopPeriodic() {
        Scheduler.getInstance().run();
    }


cstelter 05-02-2015 12:24

Re: How to Program Mecanum
 
Building on last post--

When you push teleop mode on Drive station, IterativeRobot will call teleopInit() and then call teleopPeriodic() every 20ms.

Similarly when you press Autonomous from drive station, it calls autonomousInit() and then autonomousPeriodic() every 20ms after that.

Your autonomousPeriodic() directly calls your drivetrain so you are making that call every 20ms in autonomous. This is why this mode works for you.

Note, you should *never* call any subsytem functionality from anything but a command. You are only asking for trouble.

Your autonomousPeriodic() *should* be:

Code:

    public void autonomousPeriodic() {
        Scheduler.getInstance().run();
    }

You should create a command field in your Robot class
Code:

public class Robot extends IterativeRobot {
    Command autonomousCommand;
    ...

and then you can do something like this in autonomousInit:
Code:

    public void autonomousInit() {
        // schedule the autonomous command (example)
        if (autonomousCommand == null) {
            autonomousCommand=new leftStraffe();
        }
        autonomousCommand.start();
    }

Now, when you run autonomous, we simply run the scheduler. The autonomous starts your leftStraffe command (note, java convention is to name classes with a captial so LeftStraffe may be a better name because you will have to look back less to see how you spelled it if you are consistent with your naming conventions), so that command is now being controlled by the scheduler. It will call execute() which in turn will be the appropriate way call your mecanum drive function.

cstelter 05-02-2015 12:31

Re: How to Program Mecanum
 
Just one more thing I'm compelled to point out....

Quote:

Originally Posted by LFRobotics (Post 1438714)
Okay that didn't work either. Nothing works.

FRC is the hardest fun you'll ever have. If it always worked the first time you might have fun, but it wouldn't be hard and you probably would learn less.


Quote:

Originally Posted by LFRobotics (Post 1438714)
The program uploads - the DS doesn't through any errors - it shows all green lights - but nothing happens with the Joysticks - I can press anything on the XBox controller and nothing happens. I can still make the robot move using ,my preassigned values in autonomous.

Wait a second! The above is in direct contradiction to your 'Nothing Works' assertion! (all is not lost-- your autonomous moves!!!!)

Don't be discouraged. You're living the FRC dream my friend. You're facing challenges looking for answers. This is my life too-- I'm a 25 year professional software engineer. I've had these moments too.

But the true joy will come in learning, and building on what you have learned. Every time I get stuck in my job, I'm on stackoverflow or google searching for a solution to my particular problem. But I would not have gotten as far as I have by concluding 'Nothing Works'. Don't go there.

You *will* get through this.

cstelter 05-02-2015 16:36

Re: How to Program Mecanum
 
Quote:

Originally Posted by Ether
Quote:

Originally Posted by 3786KRRobotics
If you want to strafe to the left, you want to drive the front left forward and rear left backwards while driving the front right backwards and the back right forwards. This creates a vector in only the left direction.

Not. The wheel speeds described above are all the reverse of what they should be.

I've learned to trust Ether so I'm trying not to doubt this, but it seemed wrong to me the first time I read it.

Quote:

Originally Posted by Ether (Post 1437765)

Quote:

Originally Posted by 3786KRRobotics
when strafing, one side should have the wheels rotating towards the outside when viewed side on, and the other side should be rotating inwards.

Just to be clear:

Assuming your wheels are mounted correctly,

Strafe Left:
- Left wheels rotate "inward"
- Right wheels rotate "outward"

Strafe Right:
- Left wheels rotate "outward"
- Right wheels rotate "inward"

... which is not the same as this:

Quote:

Originally Posted by 3786KRRobotics
If you want to strafe to the left, you want to drive the front left forward and rear left backwards while driving the front right backwards and the back right forwards. This creates a vector in only the left direction.



The above didn't help me as I'm not able to visualize inward outward-- I can interpret it two different ways-- inward from the top or inward from the bottom?

My thinking is that the left front wheel driving forward means the direction that would carry the robot toward what we are calling the front i.e. counterclockwise when viewed from the left side of the robot.

So on the bottom we have a diamond and that tells me that the wheel rotating that way should create force in the forward and the left direction. (in sand, all the sand would wind up on the right side of the wheel and behind the wheel).

Likewise if I drive the left rear wheel backwards (i.e. clockwise when viewed from the left) or the direction that would carry the robot to its rear if they were normal wheels then that diamond on the bottom will be forcing the robot backwards and to the left.

Summing those, the forward and back cancel and there should be a net left motion out of the left.

On the right if you drive the front right backward (counterclockwise when viewed from the right), the angle from below is identical to the back left wheel which we also drove backwards so again that wheel should be pushing backwards and left (in my eye).

And finally the rear right wheel driving forward (clockwise when viewed from right), so here as in the left front I see it should be pushing foward and left.

So the original position by 3786KRRobotics still seems correct to me. I count equal forces forward and backwards with his incantation and a left force from all wheels.

Yet everyone else seems to agree with Ether and common sense says I should too-- but I must be missing something obvious.

Can anyone point out where I'm thinking wrong?

I need an obviator-- one who can point out the obvious to me because at the moment I can't see it.

Maybe there is something fundamental I'm just not grasping-- we used RobotDrive to handle all this for us and it works fine so I never had to properly think though it.

LFRobotics 05-02-2015 16:55

Re: How to Program Mecanum
 
Okay THANKS for all the help! I changed it and it works for forwards/backwards and straffing - I am going to program turning with the buttons. Now I am trying to program pnuematics and I did it last year and it was easy but all my button assignments don't work this year - I have the updated mappings too - here is the new code:

https://github.com/MrSTUDofCODE/NewM...team4623/robot

THANKS again!

cstelter 05-02-2015 17:43

Re: How to Program Mecanum
 
Quote:

Originally Posted by LFRobotics (Post 1438900)
Okay THANKS for all the help! I changed it and it works for forwards/backwards and straffing - I am going to program turning with the buttons. Now I am trying to program pnuematics and I did it last year and it was easy but all my button assignments don't work this year - I have the updated mappings too - here is the new code:

https://github.com/MrSTUDofCODE/NewM...team4623/robot

THANKS again!

Hooray! It's working.


I see you have created a subsystem and commands for pneumatics, and Scheduler is being run in telopPeriodic so lots looks right there.

You have buttons to schedule your commands to extend and retract, so that looks good.

But you took a shortcut and went away from subsystem/command for your drive train. I would reintroduce the old mecanum subsystem you used to have and move the motors and the mecanumDrive function you currently have on Robot to that subsystem.

I would set the defaultCommand (as in the old version) to DriveTele-- this will automatically schedule DriveTele at startup.

Then in execute() of DriveTele, you can make your call to Robot.mecanum.mecanumDrive() as you are currently doing in teleopPeriodic().

This will work better long term than the shortcut.

Flow *should* be
  1. Default Command DriveTele scheduled at statrup
  2. teleopPeriodic()
  3. Scheduler.getInstance().run()
  4. Scheduler calls DriveTele.execute()
  5. DriveTele.execute() calls mecanum.mecanumDrive()
  6. if you are pressing the one button, extend will be scheduled and you will next go to
    extend.execute()
    if pushing retarct, the retract.execute() will get called
    or if neither button pressed we are done with Sheduler.run
  7. Repeat back at step 2

You have taken a shortcut for your mecanumDrive call and gotten rid of steps 1, 3,4,5 and instead hardcoded what should be in DriveTele.execute and put it just before the last step to repeat.

It's better for Scheduler to schedule a default DriveTele command and manage calls to execute than for you to directly call mecanumDrive() on Robot without any command or subsystem.

Ether 05-02-2015 17:43

Re: How to Program Mecanum
 
Quote:

Originally Posted by cstelter (Post 1438887)
The above didn't help me as I'm not able to visualize inward outward

I don't care for that nomenclature either; I was using it because that's the way the questioner (3786KRRobotics) worded it.

I hope the following is clearer for you:

vehicle forward:

- both left wheels rotating CCW (when viewed from left side of vehicle)

- both right wheels rotating CW (when viewed from right side of vehicle)


vehicle strafe right:

- front wheels turning CCW (when viewed from their respective sides)

- back wheels turning CW (when viewed from their respective sides)


vehicle rotate CW (as viewed from above):

- all 4 wheels rotating CCW (when viewed from their respective sides
Vehicle backward, strafe left, and rotate CCW: each wheel turning the opposite direction of the forward, strafe right, and rotate CW cases, respectively.



cstelter 05-02-2015 23:57

Re: How to Program Mecanum
 
Quote:

Originally Posted by Ether (Post 1438938)
I don't care for that nomenclature either; I was using it because that's the way the questioner (3786KRRobotics) worded it.

I hope the following is clearer for you:

=

vehicle strafe right:

- front wheels turning CCW (when viewed from their respective sides)

- back wheels turning CW (when viewed from their respective sides)

sides

Yes, this is perfectly clear to me now. It is consistent with what you said earlier and opposite of what the OP had indicated that you corrected. I even found a patent http://www.google.com/patents/US20130292918 also confirming the same. I have no doubt this is true.

But I still couldn't see it. I was about to post again pleading for help in my logic, but then I finally saw it. I kept thinking of the rollers-- not as rolling along their axes, but rather static.

So I had been imagining the front left wheel as it spun in reverse to strafe left. Because I was neglecting the rolling action of the rollers, I imagined that if they were digging into sand, the sand would pile up in front and to the left, pushing the wheel to the right. But finally the light went on an as I finally realized that the roller rolls in a diagonal. So on hard ground, it will push the wheel in the direction that the roller is rolling-- that is forward and left.

So, if all the rollers were stuck, would it then do the opposite as I had originally been imagining? Obviously a lot of burned rubber, but I think it might.

Of course then they probably wouldn't call them rollers!

It's a good day-- I learned something new!

LFRobotics 07-02-2015 15:08

Re: How to Program Mecanum
 
Okay I got pnuematics working like a charm - I got our lifter(window motor) working great - but turning is still an issue - I assigned it to two buttons and it does work just fine but when after i'm done turning and I want to go back to joysticks(forward/backward straffing) the controls are unresponsive unless I disable and enable again.

Also all the button mappings that I got here

http://team358.org/files/programming...rolMapping.jpg

are all screwed up. None of them are right and i've had to switch random numbers around to make it work. So if someone could point me in the direction of the real mappings that would be AWESOME

Here is the updated code: https://github.com/MrSTUDofCODE/NewM...team4623/robot

THANKS!

LFRobotics 09-02-2015 11:23

Re: How to Program Mecanum
 
Okay I got it!

cstelter 09-02-2015 12:41

Re: How to Program Mecanum
 
Quote:

Originally Posted by LFRobotics (Post 1439775)
Okay I got pnuematics working like a charm - I got our lifter(window motor) working great - but turning is still an issue - I assigned it to two buttons and it does work just fine but when after i'm done turning and I want to go back to joysticks(forward/backward straffing) the controls are unresponsive unless I disable and enable again.
THANKS!

I think I see what you did to fix the turn problem. You started with a whilePressed command to turn right or left and you also had a whenReleased that called the command baseStop.

Your framework was good I think, but your commands needed just a minor tweak.

Your solution seems to be to check the button state in DriveTele execute() method. I think this code works, but could be a bit cleaner.


Here is the new code in DriveTele

Code:

    protected void execute() {
            Robot.mec.mecanumDrive(
                (oi.stick.getLeftJoyX()+oi.stick.getLeftJoyY())/2,
                (oi.stick.getLeftJoyY()-oi.stick.getLeftJoyX())/2,
                -(oi.stick.getLeftJoyY()-oi.stick.getLeftJoyX())/2,
                -(oi.stick.getLeftJoyX()+oi.stick.getLeftJoyY())/2);
           
            if(oi.stick.getRawButton(5)) {
                    Robot.mec.turnLeft();
            }
           
            if(oi.stick.getRawButton(6)){
                    Robot.mec.turnRight();
            }
    }

First of all, in the case where a button is pushed-- you first tell the drivetrain to drive off the joysticks. Then if 5 is pressed you immediately tell it to turnLeft. If both are pressed, it will then make a 3rd call to turn right. You essentially send all 1, 2 or 3 directions quickly to the drivetrain and then wait 20ms for the next call to execute(). It may be harmless to send all these alternative powers to the controllers, but it is also unnecessary. Cleaner may be

Code:

    protected void execute() {
            if(oi.stick.getRawButton(5)) {
                    Robot.mec.turnLeft();
            } else if(oi.stick.getRawButton(6)){
                    Robot.mec.turnRight();
            } else {
                  Robot.mec.mecanumDrive(
                (oi.stick.getLeftJoyX()+oi.stick.getLeftJoyY())/2,
                (oi.stick.getLeftJoyY()-oi.stick.getLeftJoyX())/2,
                -(oi.stick.getLeftJoyY()-oi.stick.getLeftJoyX())/2,
                -(oi.stick.getLeftJoyX()+oi.stick.getLeftJoyY())/2);
        }
           
    }

This way you only send one set of commands to the drive train every 20ms on telopPeriodic.

I believe your previous attempt could have worked too with just a couple tweaks. I think the reason you lost control was becuase of your baseStop command. The isFinished() returns false. Once that command is scheduled by releasing a button, it scheduled itself and never returned true to isFinished() to unschedule itself. Unless another drivetrain command is scheudled, that command will keep running.

The way whilePressed() commands work is that the command is repeatedly scheduled to run as long as the button is triggered. But when it is released no action is taken, so a quick press or a long press has little difference other than the command is repeatedly instantiated longer on a long press.

The whileHeld() on the other hand will cancel the command when the pressing action stops. When it does this, it doesn't matter that your command may be saying isFinished() is false. It's going to de-schedule when the button is released. In this way your default command for the drive train (DriveTele) will again take over.

So I think the original code could be fixed 3 different ways in addition to the solution you chose.

1) return true from isFinished() in your turn-right or turn-left commands-- then each time through the loop, they will do the turn and then be done and as long as the button is pressed it will reschedule each time and continue sending the command until the button is released. In this case you can remove the stop whenReleased() calls to baseStop because as soon as the button is released your turn command will have finished and it will revert to DriveTele

2) Keep the whenPressed and change the baseStop to return true. Then the baseStop will interrupt the turnRight command and stop. Actually-- I'm not sure this will work-- I'm not that intimate with the code so possibly after baseStop, it might fall back to most recently interrupted command (the turn command) or possibly the interruption will have fully cancelled the command in which case you'd fall back to driveTele. I'm not 100% sure on this but I think there is a solution in this direction.

2) Probably easiest to understand (and quite honestly the one I'm most confident would work) is to use whileHeld() instead of whenPressed() and no other changes are required apart from removing the two stop whenReleased baseStop commands. There is no need for a stop with whileHeld-- it will go to DriveTele as soon as it is no longer held which will then send all stop (if no-one is touching joystick) or send whatever the joystick is sending.

I think the solution you chose was fine, but I wanted you to understand why the previous version was failing.

mac 09-02-2015 13:51

Re: How to Program Mecanum
 
Hello. How far have you trouble shot. Is the radio working both ways? Has the robot done any commands? Can you hard wire it to run? Fresh battery? My 3 cents. Thank You Thomas (just give me a crabcake) McCubbin


All times are GMT -5. The time now is 11:16.

Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi