Hi! This year is my first year Owasso, OK has ever had a robotics team. I happen to be the one and only programmer. Unfortunately, no one has past experience with robotc. Fortunately, I've learned some of it.

But back to the problem; I'm trying to control a tetrix servo with one button, where if you press it once, it moves to a certain position. And if you press it another time, it moves back to the original position. This is what I currently have:

This works, just not perfectly. When I press the button, it hesitates, and sometimes doesn't even go. So usually, I press it once quickly, and either it shakes and moves to the position, or it just shakes and stays there. Can anyone help me make a better way to program this? Any contribution will be greatly appreciated.

Thank you.

Thu Dec 13, 2012 10:29 pm

magicode

Moderator

Joined: Tue Sep 14, 2010 9:19 pmPosts: 496

Re: one button controlling help

The "problem" here is that the processor is runs through your code extremely quickly. Even when you press the button really fast, the loop executes many times during that press. This means that the value is continuously switched between 20 and 100. Let me know if you want a more in depth explanation of this.

Here is some pseudocode showing how to accomplish what you want to do:

Code:

bool buttonAlreadyPressed = false; // boolean variable to hold the previous state of the buttonwhile(true){ if(button is pressed){ if(!buttonAlreadyPressed){ //Only execute if the button is being pressed for the first time since being released buttonAlreadyPressed = true; // now it's been pressed, so don't execute this next time, until you release and press it again if(ServoValue[servo4] > 60){ servo[servo4] = 20; } else{ servo[servo] = 100; } } } else{ //button isn't pressed buttonAlreadyPressed = false; // now the button has been released }}

_________________sudo rm -rf /

Thu Dec 13, 2012 11:31 pm

MHTS

Guru

Joined: Sun Nov 15, 2009 5:46 amPosts: 1523

Re: one button controlling help

Another way to look at it is to break the problem down to the following sub problems:1. Declare a variable that remembers the current position of the motor and program the motor to the current position specified by this variable.2. Program a button to toggle the variable to the two possible positions when it is pressed.

So let's say you have an arm controlled by a servo motor and you have two possible positions: arm up (0) and arm down (120).

To solve problem 1, the code looks something like this:

Code:

int armPos = 0;

while (true){ servo[armServo] = armPos; wait1Msec(100);}

To solve problem 2 is a little trickier. Your code must detect a button transition event instead of monitoring if the button is pressed. Like Magicode said, the processor runs really fast. If you toggle the position on each robot loop when the button is remained pressed even very briefly, you are going to toggle at least 10's of times. However, if you detects the transition of the button from "not pressed" to "pressed", you will only have one per button press no matter how long you keep the button pressed. To detect button transition event, the code looks something like this:

Thanks for the help on the coding! I appreciate you telling me about how the processor runs through too quickly, but, if it is convenient, could you explain a little more on it? (It might help for future years and present problems.)

Thanks.

Sat Dec 15, 2012 11:57 am

magicode

Moderator

Joined: Tue Sep 14, 2010 9:19 pmPosts: 496

Re: one button controlling help

Sure thing. Imagine that you have this code:

Code:

int i = 0;while(true){ if(button pressed){ i = i + 1; }}

What will the value of i if you hold down the button for 1 second? Well, I don't have the information to calculate it exactly right now, but it will a very, very big number.

Quote:

Technical info, ignore if you don't want to read it:

It would be be in the tens of millions. In fact, the integer variable is not big enough to hold this number (an integer on the NXT is only 2 bytes, which means you can only hold about 32,000 numbers in the positive direction), and it will overflow. This means it will wrap around, and start holding negative numbers. This will happen again and again, multiple times a second.

This is because the processor computes things very quickly (compared to us humans). For example, the main processor in the NXT runs at 48 Million cycles per second. This is why we have to make sure that the instruction only executes once when the button is pressed for the first time after being released. Does that clear things up, or am I still being unclear?

Aside: does anyone know about cycles per instruction for computation with ROBOTC? I know the NXT architecture does integer computation at 1 CPI, but how much overhead does ROBOTC create?

_________________sudo rm -rf /

Sat Dec 15, 2012 1:15 pm

MHTS

Guru

Joined: Sun Nov 15, 2009 5:46 amPosts: 1523

Re: one button controlling help

I believe RobotC is not running code natively. It's some sort of VM with byte code interpreter. So it is not as fast as running native code but still much faster than you can release your finger on the button. Therefore, don't count on reacting once when the button is pressed. It will for sure react multiple times a second.

Sat Dec 15, 2012 8:43 pm

amcerbu

Novice

Joined: Sun Oct 21, 2012 10:01 pmPosts: 76

Re: one button controlling help

@MHTS: I recall reading somewhere that RobotC compiles to some sort of bytecode (sort of like C# or Java, I guess), rather than running native NXT machine code. That would also explain why I've never crashed a brick with a RobotC program.

I've never tried it in RobotC; what does writing outside the bounds of an array do, after all (I'm all too aware of the consequences in C++)?

Sat Dec 15, 2012 11:13 pm

MHTS

Guru

Joined: Sun Nov 15, 2009 5:46 amPosts: 1523

Re: one button controlling help

amcerbu wrote:

@MHTS: That would also explain why I've never crashed a brick with a RobotC program.

No, it's still possible to crash RobotC. I have seen it a number of times

Sun Dec 16, 2012 12:56 am

skatefriday

Novice

Joined: Tue Dec 11, 2012 9:19 pmPosts: 58

Re: one button controlling help

MHTS wrote:

amcerbu wrote:

@MHTS: That would also explain why I've never crashed a brick with a RobotC program.

No, it's still possible to crash RobotC. I have seen it a number of times

Our brick crashed during autonomous in yesterday's competition.

Unfortunately, our drivers were not able to articulate the problemwell enough to convince the referee to reboot the brick in betweenteleop and autonomous. That's been fixed.

When that happens it's equivalent to forfeiting a match. Was a bitof a bummer because given the resulting score we very likely would have wonthat match.

Sun Dec 16, 2012 4:29 pm

skatefriday

Novice

Joined: Tue Dec 11, 2012 9:19 pmPosts: 58

Re: one button controlling help

If you notice, the RobotC documentation will tell you that youneed to wait for a servo to reach a set position before movingon in your code. This of course can create a problem if youjust use a wait function for a period of time as all other operationswill be locked out.

If you notice, the RobotC documentation will tell you that youneed to wait for a servo to reach a set position before movingon in your code.

Are you referring to the following line from the ROBOTC wiki?

Quote:

This function is used to set the position of the servos on a sensor port Servo controller. Values can range from 0 to 255. The firmware will automatically move the servo to this position over the next few update intervals. (Be sure to give the servo some amount of time to reach the new position before going on in your code.)

This simply reminds you that the servo does not move instantaneously. You can certainly set the servo value, and continue executing instructions in the same task without waiting for the servo to move to its assigned position (as long as those instructions do not depend on the servo being in the correct place). I just wanted to clear that up to avoid confusion, since your post seemed to imply that no more code could be executed in that task until the servo reached its position.

_________________sudo rm -rf /

Sun Dec 16, 2012 11:12 pm

skatefriday

Novice

Joined: Tue Dec 11, 2012 9:19 pmPosts: 58

Re: one button controlling help

magicode wrote:

skatefriday wrote:

If you notice, the RobotC documentation will tell you that youneed to wait for a servo to reach a set position before movingon in your code.

Are you referring to the following line from the ROBOTC wiki?

Quote:

This function is used to set the position of the servos on a sensor port Servo controller. Values can range from 0 to 255. The firmware will automatically move the servo to this position over the next few update intervals. (Be sure to give the servo some amount of time to reach the new position before going on in your code.)

This simply reminds you that the servo does not move instantaneously. You can certainly set the servo value, and continue executing instructions in the same task without waiting for the servo to move to its assigned position (as long as those instructions do not depend on the servo being in the correct place). I just wanted to clear that up to avoid confusion, since your post seemed to imply that no more code could be executed in that task until the servo reached its position.

Right. I was not trying to imply that at all. That would bea gross misunderstanding of how the software works.

The discussion was in the context of how to respond when you are in an event loop looking for button presses and the response to oneof those button presses is to move a servo. Noting that if a secondpress of the same button moves the same servo that there willbe contention for servo position given that, without doing somethingto lock out that button for a period of time.

The approach of using a second task to manage the semaphore thatlocks out the servo move button during the portion of time the servo ismoving, but allows the event loop to continue processing other user actions simply illustrates the point.

BTW, that's not a good reason to use task. Strictly speaking, that code does not resolve contention. By using task, you may introduce contention. From the description of your problem, why not implementing it like the following?

Now the above code does not "wait for the previous servo move" to complete before toggling to the previous position. But in my opinion, that would be how I want it anyway. For example, if my robot arm is moving to the wrong position, I hate to wait for it to complete the move before I can correct it. If you insist that it should complete the previous move, you could do the following instead:

BTW, that's not a good reason to use task. Strictly speaking, that code does not resolve contention. By using task, you may introduce contention. From the description of your problem, why not implementing it like the following?

Now the above code does not "wait for the previous servo move" to complete before toggling to the previous position. But in my opinion, that would be how I want it anyway. For example, if my robot arm is moving to the wrong position, I hate to wait for it to complete the move before I can correct it. If you insist that it should complete the previous move, you could do the following instead:

I guess it depends upon how you define contention. I was defining it the way that I thought the original poster was. That is that if you expect a button press to move a servo to a particular location andthat button press is being monitored in an event loop and that buttonis also used to move the servo to a second position, toggling betweenthe positions, then contention is defined as the tendency of the buttonpress to appear as a single press to the human, but in fact is read asstill pressed for a period of time within the event loop which causes theservo to toggle back and forth fast enough to appear "hesitant" or twitchy.

Who is online

Users browsing this forum: No registered users and 2 guests

You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum