Is there a way to disable motors in RobotC that is different than merely assigning their power level to zero and which overrides any other command to the motor?
I’m teaching a kid to program using a clawbot with no joystick. The kid writes a program, downloads, it, then cycles power on the Cortex and watches what happens.
I would like to write a piece of code the kid can always place into the program so that, no matter what, the robot will shut down after, say, 15 seconds or so. It’s to allow the kid to be able to recover the robot (if the program goes crazy) without having to grab it as it whizzes around the floor.
I thought about writing a separate task that would do nothing but monitor a watchdog timer and shut down the motors after 15 seconds. But I think the usual assigning of motor power to zero would simply cause a battle between the main task and the watchdog timer task, so I’m looking for a “deeper” solution.
EDIT: I guess I’m looking for a command that will shut off all motors without my needing to know what the names of the motors are. If the kid adds a motor or renames a motor, I don’t want my watchdog task to need to know what the motor name is in order to kill it.
Super hacked together solution
Task watchdog{
Wait 15000
Stop motors
While(1l){}
}
The other far cleaner way would be to just stop the user control task. Or even slight modification of the competition template of you wanted to be really fancy.
I’m assuming you don’t want to just use robotC competition control to start autonomous and just hit stop to turn off every motor. This is what I usually do. Wireless downloading is your friend
That’s very true, but this kid doesn’t have a joystick or a VexNet switch - just a clawbot, a computer, and a copy of RobotC.
I think that task would tell the motors to stop only once. If the main program then told the motors to turn on again, then this task would simply sit in its while loop and do nothing about it.
That’s an interesting idea but I don’t know if ordering a task to stop will necessarily shut off all the motors that were started in that task. I guess I’ll have to test that and see.
If you do stop the task you have to tell motors to stop right after. Stopping task just ensures no more commands get sent but doesn’t actually stop the last command. This solution still requires watchdog task.
The hacky solution I posted had the while loop just to hog the processor so the control task couldn’t send any more commands. That’s what makes it so hacky ;). I would have to check with jpearman about how the task system works and when it gives the next task a turn if the task never has any waits.
Stopping the control task is the better way I just came up with hacky solution first and other while typing.
I guess I’m looking for a command that will shut off all motors without my needing to know what the names of the motors are. If the kid adds a motor or renames a motor, I don’t want my watchdog task to need to know what the motor name is in order to kill it.
Just set every port 1-10 to 0 power rather than use the names. I think there might be a stop all motors function called somewhere in competition template and I’ll go through and look for it latef today.
I guess that’s the sort of thing I’m looking for. I can’t seem to find it via Google because there are so many references to setting motor values. Thanks.
@tabor
Your idea should work if the following is done.
Have the task main as the ‘killer’ task and have the main task start the student’s task. The killer task can then stop the students task and then stop the motors before ending the program. I suspect that you will not have to even stop the motors as ending a robotc program stops the motors anyway from what I recall.
As Tabor has said, create a template that’s a bit like the competition template. Have that monitor time and then stop the “user task” after 15 seconds. Here’s an example.
/*-----------------------------------------------------------------------------*/
/* Module: userMain.c */
/* Author: James Pearman */
/* Created: 8 March 2015 */
/*-----------------------------------------------------------------------------*/
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
/* You may obtain a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/*-----------------------------------------------------------------------------*/
#ifndef USER_PERIOD_SECS
#define USER_PERIOD_SECS 15
#endif
void allMotorsOff();
void allTasksStop();
task userTask();
task main()
{
unsigned long endTime = nSysTime + USER_PERIOD_SECS * 1000;
// setup LCD
bLCDBacklight = true;
clearLCDLine(0);
clearLCDLine(1);
// start the user task
startTask( userTask );
// wait for preset amount of time
while( nSysTime < endTime )
wait1Msec(10);
allTasksStop();
allMotorsOff();
// indicate stopped
clearLCDLine(0);
displayLCDString(0, 0, "Stopped");
// block here until restarted
while(1)
wait1Msec(10);
}
// stop all motors
void allMotorsOff()
{
motor[port1] = 0;
motor[port2] = 0;
motor[port3] = 0;
motor[port4] = 0;
motor[port5] = 0;
motor[port6] = 0;
motor[port7] = 0;
motor[port8] = 0;
motor[port9] = 0;
motor[port10] = 0;
}
// Stop all tasks except main
void allTasksStop()
{
stopTask(1);
stopTask(2);
stopTask(3);
stopTask(4);
stopTask(5);
stopTask(6);
stopTask(7);
stopTask(8);
stopTask(9);
stopTask(10);
stopTask(11);
stopTask(12);
stopTask(13);
stopTask(14);
stopTask(15);
stopTask(16);
stopTask(17);
stopTask(18);
stopTask(19);
}
The students then programs in a user code file like this.
/*-----------------------------------------------------------------------------*/
/* Module: user.c */
/* Author: James Pearman */
/* Created: 8 March 2015 */
/*-----------------------------------------------------------------------------*/
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
/* You may obtain a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/*-----------------------------------------------------------------------------*/
// Uncomment to change time the user code will run
//#define USER_PERIOD_SECS 20
// Innclude the template that has the "main" task
#include "userMain.c"
// This is the user task
// Put your code here
task userTask()
{
int counter = 0;
char str[32];
displayLCDString(0, 0, "I am running");
// set motors for demo code
motor port1 ] = 50;
motor port2 ] = -50;
//
while(1)
{
sprintf(str,"%5.2f", (counter++)/100.0 );
displayLCDString(1, 0, str);
wait1Msec(10);
}
}
I found function in competition includes that does this.
allMotorsOff();
The all motors off and all tasks stop that Jpearman has in his template are directly from the competition template. Just wanted to make sure everyone sees how he went about making his template and that they are always available.
Yup. I was more just answering my own question in case anyone using the competition template later looks back at the question with stopping all motors in mind. And so people saw where you were getting a lot of the code for your template.
Create a toggle button to toggle a variable between two states. In the loops, add if statements. If toggle is in one state, execute everything as normal. Else, set all motors to zero. Once you have that set up, controlling that variable should be the easiest thing. Like, have a separate task and time 15 seconds before you change the toggle.