TBH in Autonomous

I have code that runs Take Back Half in Driver control, but it won’t run in Autonomous. I have tried two methods:

task autonomous()
{
  switch
  {
    case 0;
      starttask(TBHFlywheel);
      runauton();
     break;
  }
}

task autonomous()
{
  while(true)
  {
    if(autopick ==1)
    {
      runauton();
    }
    TBHFlywheel();// I changed it to run as a function in auton and a task in driver
    delay(del);
  }
}

Both times the intake runs, but not the flywheel and it never even says the motor values change. Anybody have any idea why? I can post the actual code if needed.

actual code might be nice. Not sure what runauton() does or how autopick is set.

In my experience with this startTask and pids and other complex things do not work well when using a code chooser… :frowning: if your not too proficient…

I don’t understand why it isn’t working… You seem to have added the


starttask(TBHFlywheel);

in task autonomous() so the code should run

Pretty sure that having it start as a task within the actual autonomous function will make it work. I don’t know much about TBH so I’m not sure if you also set a target velocity as well. If you do set a target velocity, set the target velocity within the autonomous function after you start your TBH loop.

Here is the actual code. “autopick” is set in driver control by the LCD for switching among autonomous modes.

task TBHFlywheel()//Take Back Half controller with Integral accumulator for live adjustment
{//Used for the first time successfully after a series of breakthroughs using the graphing and analysis ability
	//through debug stream and tools in Excel.
	//Finally got RPM calculation right for both encoders, and also got TBH to work over snow break from 1-20 to 1-29

	motor[launcher4] = 0;
	motor[launcher3] = 0;
	motor[launcher2] = 0;//stop flywheel ahead of time.
	motor[launcher1] = 0;
	//motor[launcher5] = 0;
	//motor[launcher6] = 0;//We use Y-splitters so motors 5 and 6 are signaled by 1 and 3, but are powered by powerexpander
	nMotorEncoder[launcher3] = 0;
	startTask(calcRPM);//start RPM calculation
	float gain = 0.00;//.003//gain for integral causes aggressive recovery of RPM after firing.
	bool running = false;
	SensorValue[flywheel] = 0;//clear flywheel encoder so prevent random data from causing error.
	bool firstcross = true;
	int prevset = 0;
	int del = 75;
	while(true)
	{
		Ferror = fRPM - altRPM;
		speed = speed + ((float)Ferror*gain);

		if(fRPM ==0)//broken code to prevent overshoot, will be removed later.
		{
			fSpeedControl(0);
			speed = motor[launcher1];
		}
		else if((Ferror>0)!= (fpreverror>0)||Ferror<-200)//if the error has changed signs (positive to negative)
		{// or the error is way overshooting, run TBH algorithm
			if(firstcross)// if it's the first time, use the approximate speed
			{
				fSpeedControl(speedapprox);
				tbh = speedapprox;
				//speed = motor[launcher1];//causes errors. to be removed.
				firstcross = false;
				gain = 0.012;//0.0065
			}
			else//If
			{
				speed = .5*(speed+tbh);//basically averages power between a lower and higher power, to get closer
				tbh = speed;// to the needed value.
			}
		}
		else
		{
			fSpeedControl(speedapprox);//if run to approxspeed incase system fails
			tbh = speedapprox;
			//speed = tbh+1;
			fpreverror = Ferror;//set previous error for algorithm above.
		}
		if(speed > 120)
		{
			speed = 120;
		}
		if(speed <0)
		{
			speed = 0;
		}
		motor[launcher4] = speed;
		motor[launcher3] = speed;//set the speed for the motors
		motor[launcher2] = speed;
		motor[launcher1] = speed;
		//fSpeedControl(speed,3);
		writeDebugStreamLine("%d,%d,%4.1f,%3.1f,%3.1d,%d",nSysTime,fRPM,altfilteredRPM,filteredRPM,speed,tbh);
		//^prints data to debug stream for grpahing and analysis of the flywheel's performance.
		//enables easier tuning and much quicker adjustment, since it logs all flywheel activities.
		delay(del);
		/*	if(prevset!=fRPM)//was commented out to debug, not sure if causes errors
		{//kept off to keep working
		firstcross = true;//if the set speed changes, use slew rate to get to approx, then use normal
		}
		else
		{//otherwise continue to check for change in set speed
		prevset = fRPM;
		}*/
		if(fRPM == 0)
		{
			firstcross = true;//resets values for the next set speed to prevent errors.
			tbh= 0;
			del = 85;
			gain = 0.0;
		}
		else
		{
			del = 75;
		}
		fpreverror = Ferror;
	}
}
task autonomous()
{

	switch(autopick)//We use a switch case statement to choose autonomous for ease of scalability
	{		//and because it is easiest to integrate with the LCD picking in driver mode.
	default://any extraneous case caused by a bug, goto basic autonomous
		autopick = 0;
		break;
		//\/\/\/\/\/\/
	case 0:
		shots = 0;
		clear();
		startTask(TBHFlywheel);//This does not work, as it says the task is always waiting or not running
		fRPM = 2660;//get to correct speed using TBH
		speedapprox = 78;//set approximate speed for quick firing.
		wait1Msec(2000);
		autoIntake(100,0,0);
		wait1Msec(2000);
		autoIntake(100,0,0);
		wait1Msec(2000);
		autoIntake(100,0,0);
		wait1Msec(2200);
		autoIntake(100,0,0);
		fRPM = 0;//spin down if finished early.
		break;
		//\/\/\/\/\/\/
	case 1:
		clear();
		stopTask(TBHFlywheel);
		stopTask(usercontrol);//it works if I stop both tasks. Maybe stopping Usercontrol will prevent FRPM from being reset.
		spinUP(81);//SpinUp manually increases speed using a safe slew rate
		wait1Msec(2500);
		autoIntake(85,2);
		spinUP(84);
		wait1Msec(300);
		spinUP(81);
		wait1Msec(600);
		autoIntake(85,0);
		spinUP(84);
		wait1Msec(300);
		spinUP(81);
		wait1Msec(600);
		autoIntake(85,0);
		spinUP(84);
		wait1Msec(300);
		spinUP(81);
		wait1Msec(600);
		autoIntake(85,0);
		spinUP(0);
		startTask(TBHFlywheel);
		break;
		//\/\/\/\/\/\/
	case 2:

		break;
		//\/\/\/\/\/\/
	case 3:
		EncoderBase(100,1750);//old autonomous to capture balls.
		wait1Msec(100);
		EncoderTurn(100,510,right);
		wait1Msec(100);
		EncoderBase(100,1000);
		wait1Msec(100);
		EncoderTurn(100,180, right);
		wait1Msec(100);
		EncoderBase(100,300);
		wait1Msec(100);
		EncoderTurn(100,180, right);
		wait1Msec(100);
		motor[intake] = -100;
		EncoderBase(100,700);
		stopbase();
		motor[intake] = 0;
		break;
	case 6:

		break;
	case 7:
		shots = 0;
		clear();
		stopTask(usercontrol);
		stopTask(TBHFlywheel);
	//	fRPM = 2300;//get to correct speed
		spinUP(67);//get to correct speed
		wait1Msec(2000);
		while(shots <=30)// run while shots is less than or equal to 30
		{
			autoIntake(90,0,1);//intake without time out, both rollers
			spinUP(69);//recover lost energy in wheel by increasing voltage
			wait1Msec(600);//wait for work to finish
			spinUP(67);//adjust to correct speed again
			wait1Msec(200);//wait for adjust
			shots++;//increment shots taken.
		}
		fRPM = 0;//spin down if finished early.
		startTask(TBHFlywheel);
		break;
	}
}

Hope this helps. It is a bit messy because of the comments I made for the notebook.

in the first example after “case 0” you have a “;” instead of a “:” which is probably while the task isn’t initializing.

It’s hard to tell what the problem is without seeing all the code. However, this comment


startTask(TBHFlywheel);//This does not work, as it says the task is always waiting or not running

makes me wonder if the task has been started, the task will in fact spend most of it’s time waiting, that’s what the delay(del); statement is designed to do and what you actually want to happen.

How do you guys embed your code so it shows up in the forum post like it does in robotc with all the colors? I’m only trying to make it easier for people to see and follow.

You use the [code/code] tags.

I have but it’s still not showing up correctly. Maybe I need to place the code between the slashes?

Sorry, my post was incorrect. In the menu above the text box where you type replies there is a small tag that reads </>. Click on that and the code tags will appear.

Problem Solved . I just had to stop usercontrol in auton and it worked great for our skills night.