View unanswered posts | View active topics It is currently Thu Aug 21, 2014 8:03 pm






Reply to topic  [ 14 posts ] 
Kill Switch 
Author Message
Rookie

Joined: Mon Oct 27, 2008 5:41 pm
Posts: 5
Post Kill Switch
Is it possible in RobotC to create a "Kill Switch" to cut power to all the motors?
maybe an if statement to set it to button 10... im not sure of what to do...


Mon Oct 27, 2008 5:53 pm
Profile
Expert

Joined: Mon Oct 27, 2008 9:59 pm
Posts: 137
Post Re: Kill Switch
goteam327,
You should be able to check for such a disable button being pressed in an outer loop of a tele-op loop after getting the latest joystick state from a bluetooth packet:
Code:
getJoystickSettings(joystick);

You could assign such a kill switch to any button. For example, if you wanted to use button 10, you would check to see if the button was pressed using something along the lines of:
Code:
if(joy1Btn(10) != 0)

Inside if your if block you would either manually set all your motors to zero and set your servos to their current target... or call a separate function to do the same.
Code:
if(joy1Btn(10) != 0) {
  kill();
}

Note that you would have to define such a kill() function according to standard C rules prior to your main() function. Inside of this hypothetical kill() function you would manually set each actuator to an idle value.
Code:
void kill() {
//pretend we have two motors, D & E we want to stop
motor[motorD] = 0;
motor[motorE] = 0;

//pretend we have two servos, 1 & 2 we want to stop
servoTarget[servo1] = ServoValue[servo1];
servoTarget[servo2] = ServoValue[servo2];
}

Note that we did not set the servo targets to zero. This would have caused the servo to move to the far left position, not to stop. To stop it, we just set the target to the current position.

Now... we get to another question... the question I actually intended to post myself. When we set a motor's speed to zero, we are stopping it by apply breaking. There are some cases where we may not want to hold the break on a motor as it can be a real drain on the battery. An example of when I would want to stop the motors, but not continue to apply breaking is between autonomous and tele-op modes. My code may be running a single program and I may want to stop the robot when the stopbit becomes enabled, but not hold the breaks while the refs tally the scores from autonomous. Here I may want to leave the motors idle without applying power.
Looking at the robotC API, I see one possible answer to this. Since the motors use PWM, there is a function to set whether to float/coast when idle:
Code:
bFloatDuringInactiveMotorPWM = true;

Can anyone confirm if this is the correct usage for this function and if there is a corresponding function for the servos?

Thanks,
l0jec


Mon Oct 27, 2008 10:42 pm
Profile
Guru
User avatar

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Post Re: Kill Switch
hi,
I suggest not to use a void but a task for this issue.

I did this in my lawn mower robot like

Code:
task EmergencyBrake()
int i;
{
  while true()
  {
    if (SensorValue(S1)!=0)  // Touch at S1 was MY Emergency Button, you'll have to change this!
        {
          for (i==0; i<3; i++) {motor[i]=0;}
          StopAllTasks();
        }
    wait1Msec(20); // give other tasks a chance...
  }
  return;
}

task main()
{
  StartTask (EmergencyBrake);
  //... rest of your code
}



your 2nd question, first part:
yes,
Code:
bFloatDuringInactiveMotorPWM = true;
is the correct usage for switching to "floating/casting mode", but for Lego encoder motors it's working faulty (see different thread).
Concerning any usage for servos - I unfortunately don't know.

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;task main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PutPixel(x,y);}}}while(1)}


Tue Oct 28, 2008 7:09 am
Profile
Creator
Creator

Joined: Fri Feb 09, 2007 9:21 am
Posts: 614
Post Re: Kill Switch
The simplest thing is to use a call to "StopAllTasks()" whenever the "kill" switch is pushed. This will abort the running program. Part of the cleanup process upon program termination is to stop all possible motors.

You have several choices for the "Kill" switch:
  • It could be a touch sensor mounted somewhere on your program
  • It could be one of the buttons on the PC game controller.
  • It could be one of the buttons on the NXT front panel. But then of course, you could simply use the dark grey button to do the same.

Using a separate task to monitor the kill switch is a good idea because it helps protect against errors in main task that may prevent the "check for kill switch" condition from being reached.


Thu Oct 30, 2008 11:53 pm
Profile
Rookie

Joined: Sat Nov 29, 2008 4:21 am
Posts: 4
Post Re: Kill Switch
To do a kill switch with the joystick I simply put an if statement in the loop for task main that breaks the loop.
Code:
task main()
{
while (true)
{
...
if (joystick.joy1_Buttons & button10)
            break;
...
}
StopAllTasks();
}

_________________
Ian McBride
Benson Robotics Club


Sat Nov 29, 2008 3:39 pm
Profile
Expert

Joined: Mon Oct 27, 2008 9:59 pm
Posts: 137
Post Re: Kill Switch
As long as this thread has been resurrected... I thought I'd point on a problem with an earlier assumption I had made.
The code below will simply not work:
Code:
servoTarget[servo1] = ServoValue[servo1];

This is because ServoValue[] does not contain the actual position of the servo; but rather the last target set for the servo. Since the servo's target may not have been reached, setting the target equal to the previous target does nothing to stop the movement.

Does anyone know if they is another way to kill the servo movement/power? At best it seems the students will have to set a 'home' position for the servos, set that as the target in a kill function, and hope the robot can move to that position quickly enough when the stop bit is enabled by the FMS...


Sun Nov 30, 2008 9:10 pm
Profile
Professor

Joined: Fri Sep 19, 2008 1:22 am
Posts: 200
Post Re: Kill Switch
That should not be a problem. The current design of the FMS actually kills your program when your time is up. I'm pretty sure that killing the program will also immediately stop any motor and servo motion. You can test this easily enough yourself by starting a servo moving and then hitting the grey button the NXT to kill the program.

_________________
Jeff McBride
Benson Robotics Club


Sun Nov 30, 2008 9:45 pm
Profile
Creator
Creator

Joined: Fri Feb 09, 2007 9:21 am
Posts: 614
Post Re: Kill Switch
There is an option on the HiTechnic sdervo controller to stop sending updates to the servos. For some servos, this will disable the servo electronics and put it into "coast" mode where it stops moving. The servo controller starts up in this state.

IF there was real value for it, it would be possible to add a feature to ROBOTC to immediately enter this state. The way the hardware is implemented, it applies to all servos on a controller and not just a single servo.


Mon Dec 01, 2008 12:13 pm
Profile
Professor

Joined: Fri Sep 19, 2008 1:22 am
Posts: 200
Post Re: Kill Switch
I suggest testing what happens when you order a servo to move using NXT-G and then kill the app and see if the NXT-G firmware sets the servos to coast mode or not. The RobotC firmware should do the same thing as the NXT-G firmware. That way robots in competition will all behave the same regardless of the software platform.

Also, adding a RobotC API to give programmers access to this would be a nice addition for a future release.

_________________
Jeff McBride
Benson Robotics Club


Mon Dec 01, 2008 2:58 pm
Profile
Expert

Joined: Mon Oct 27, 2008 9:59 pm
Posts: 137
Post Re: Kill Switch
Quote:
That should not be a problem. The current design of the FMS actually kills your program when your time is up. I'm pretty sure that killing the program will also immediately stop any motor and servo motion. You can test this easily enough yourself by starting a servo moving and then hitting the grey button the NXT to kill the program.


Without testing, I have one concern with that. FIRST has stated that you could use dual or single program mode and from what you describe, wouldn't killing the program at the end of the autonomous match mess up any teams with a single program (they would have to reset/restart the program to get their tele-op code to work)?
I thought they were simply going to toggle the enable bit which the students need to check for in the code???


Mon Dec 01, 2008 7:07 pm
Profile
Professor

Joined: Fri Sep 19, 2008 1:22 am
Posts: 200
Post Re: Kill Switch
l0jec wrote:
Without testing, I have one concern with that. FIRST has stated that you could use dual or single program mode and from what you describe, wouldn't killing the program at the end of the autonomous match mess up any teams with a single program (they would have to reset/restart the program to get their tele-op code to work)?
I thought they were simply going to toggle the enable bit which the students need to check for in the code???


That was our original understanding as well. However, they seem to have changed their minds. The current behavior of the FMS as it has been described to me is that it will always kill your program at the end of the autonomous period and will either restart it (same as pressing the orange button again) or run the specified program if you have a dual program configuration.

The key thing to do in your single program code is to wait for the StopPgm flag to clear and then switch on the UserMode flag to run either your autonomous or your driver control function.

We created a template that looks like this:

Code:
#include "JoystickDriver.c"

void autonomous()
{
    // autonomous code goes here
}

void drive()
{
    // user drive code goes here
}

task UserCode()
{
    if (joystick.UserMode)
        drive();
    else
        autonomous();
}

task main()
{
    getJoystickSettings(joystick);

    // wait for the FMS to start autonomous or driver control mode
    while (joystick.StopPgm)
    {
        wait10Msec(2);
        getJoystickSettings(joystick);
    }

    StartTask(UserCode);

    // Keep polling the joysticks and keep an eye on the stop flag.
    while (!joystick.StopPgm)
    {
        wait10Msec(2);
        getJoystickSettings(joystick);
    }

    StopTask(UserCode);
    stopMotors();
}


Note that your driver control code doesn't need to keep polling the joystick because the main task will continue to update the global joystick structure in the background.

_________________
Jeff McBride
Benson Robotics Club


Mon Dec 01, 2008 8:23 pm
Profile
Expert

Joined: Mon Oct 27, 2008 9:59 pm
Posts: 137
Post Re: Kill Switch
Jeff,
If that is the case... I wonder when was FIRST planning to share that bit of information. Our regional is this coming weekend (12/6) and it would be nice to know these things ahead of time.

I think my best bet is to take your template and ours, and merge the two. Your template example appears to work for restarting the program, but if the FMS simply changes the enable bit... your robot would be in trouble. The only safe bet at this time is to code it to be able to come up in either auto/tele mode, but also be able to switch between them/kill the actuators if the FMS does what FIRST originally said.

Also, just out of curiosity, do you know how StopTask() functions (ie, does in interrupt the target task/thread & if so, can that task/thread catch the interruption to do cleanup, etc.)? I haven't seen any documentation on that...

-l0jec


Tue Dec 02, 2008 10:36 am
Profile
Professor

Joined: Fri Sep 19, 2008 1:22 am
Posts: 200
Post Re: Kill Switch
From the help file:

StopAllTasks();
Stops execution of the current program.

StopTask(TaskID);
Stops execution of a single task.


Note: TaskID is the name of the task.

I will post a question to the FTC Forum asking for final clarification about the behavior of the FMS.

If necessary, you can change the main task to look like this:

Code:
task main()
{
    while (true)
    {
         getJoystickSettings(joystick);

         // wait for the FMS to start autonomous or driver control mode
         while (joystick.StopPgm)
         {
             wait10Msec(2);
             getJoystickSettings(joystick);
         }

         StartTask(UserCode);

         // Keep polling the joysticks and keep an eye on the stop flag.
         while (!joystick.StopPgm)
         {
              wait10Msec(2);
              getJoystickSettings(joystick);
         }

         StopTask(UserCode);
         stopMotors();
    }
}

_________________
Jeff McBride
Benson Robotics Club


Tue Dec 02, 2008 11:21 am
Profile
Professor

Joined: Fri Sep 19, 2008 1:22 am
Posts: 200
Post Re: Kill Switch
I received a reply to the question on the FTC Forum. Yes, the FMS will kill your program at the end of the autonomous period even in a single program configuration.

_________________
Jeff McBride
Benson Robotics Club


Wed Dec 03, 2008 11:43 pm
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 14 posts ] 

Who is online

Users browsing this forum: No registered users and 2 guests


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

Search for:
Jump to:  



Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.