I'm missing something simple

Hey gang,

I’m hoping that someone here can explain to me what I’m doing wrong in my code. I’m pretty new to this and I’m sure it’s something that will be obvious to someone who knows more about coding.

I have 2 functions, named “task1” and “Task2” that both run properly individually. Task1 completes substantially quicker than Task2.
When I try to programatically call them in a loop, the robot behaves as if it’s not waiting for Task2 to finish before it starts Task1 again.


void task1(int time, power)
{
Do some stuff here
}

void task2(int encValue, power)
{
Do other stuff
}

task main()
{
	while(true)
	{
		if(vexRT[Btn8D] == 1)
		{
		task1 (5,30);
		task2 (1400,30);
		task1 (2, -30);
		task2 (2100, 50);
		}
	}
}

It looks like since Task2 (1400,30) takes a few seconds to finish, task1(2,-30) is starting before Task2 (1400,30) is done and we can’t figure out why.

Can anyone help please?

You need an “int” in front of both powers. See if that works.

Hey, thanks for the help!

Yes, that was my oversight trying to pseudocode that. Sorry about the goof on my part.

We’re using jpearmans “SmartMotorLib”, so the SetMotor commands are from that.

The actual code looks like this:

This is task1:


bool clawDone = false;
void claw(int time, int power)
{
	SetMotor(Claw,power);
	wait (time);
	SetMotor(Claw,0);
	clawDone = true;
}

and task2 looks like this:


void mainLift (int value, int power)
{
	if(SensorValue[lift_pot_1] < value-LIFT_THRESHOLD)
	{
		SetMotor(Lift_Motor1,power);
		SetMotor(Lift_Motor1a,power);
		SetMotor(Lift_Motor2,power);
		SetMotor(Lift_Motor2a,power);
		wait1Msec(1);
	}
	else if(SensorValue[lift_pot_1] > value+LIFT_THRESHOLD)
	{
		SetMotor(Lift_Motor1,-power);
		SetMotor(Lift_Motor1a,-power);
		SetMotor(Lift_Motor2,-power);
		SetMotor(Lift_Motor2a,-power);
		wait1Msec(1);
	}
	else
	{
		SetMotor(Lift_Motor1,0);
		SetMotor(Lift_Motor1a,0);
		SetMotor(Lift_Motor2,0);
		SetMotor(Lift_Motor2a,0);
		mainLiftDone = true;
	}
}

And task main()



task main()
{
	while(true)
	{
if(vexRT[Btn8D] == 1)
		{
				claw(1, 30); //claw(int time, int power) -------open claw
				mainLift (1800, 30); //mainLift (int value, int power)------lower lift
				claw(1, -30); //claw(int time, int power)------close claw
				mainLift (2200, 30); //mainLift (int value, int power)------raise lift
		}
}
}

Are you expecting them to run simultaneously? I guess I’m not exactly sure what the problem you are seeing is.

I was expecting this kind of behavior:

Claw opens, nothing else happens until claw is open.
Lift lowers, nothing else happens until lift is down.
Claw closes, nothing else happens until claw is closed.
Lift raises, nothing else happens until lift is raised.

What I am seeing is more like:

Claw opens, this happens fast.
Lift starts to lower, but before it gets to the bottom the claw closes again.
Lift starts back up, but before it gets to the top the claw will open

So then your power on the claw is full power and not 30?

I’m sorry, I don’t understand what you are asking me here.

My intention was that the claw either got a power of 30, or -30.


if(vexRT[Btn8D] == 1)
		{
				claw(1, 30); //claw(int time, int power) -------open claw
				mainLift (1800, 30); //mainLift (int value, int power)------lower lift
				claw(1, -30); //claw(int time, int power)------close claw
				mainLift (2200, 30); //mainLift (int value, int power)------raise lift
		}

I understand your intention. But I’m asking about the actions of the bot.

You are never actually waiting until the motor move is complete, so it just assigns the motors and falls through.

Ok, I think I understand now what you are asking.

The claw is operating at 30 power, definitely not full power.

Full power on the claw is violent and we’re not seeing that.

I think this is the piece that I’m missing.

How do I tell it to not move on to the next step until the current one completes?

You need to wait after you apply power until the pot has gotten to where you want it to go

It might be a problem with syntax. Try this:

bool clawDone = false;
void claw(int time, int power)
{
	motor[Claw] = power;
	wait (time);
	motor[Claw] = 0;
	clawDone = true;
}


void mainLift (int value, int power)
{
	if(SensorValue[lift_pot_1] < value-LIFT_THRESHOLD)
	{
		motor[Lift_Motor1] = power;
		motor[Lift_Motor1a] = power;
                motor[Lift_Motor2] = power;
                motor[Lift_Motor2a] = power;
		wait1Msec(1);
	}
	else if(SensorValue[lift_pot_1] > value+LIFT_THRESHOLD)
	{
		motor[Lift_Motor1] = power * -1;
		motor[Lift_Motor1a] = power * -1;
                motor[Lift_Motor2] = power * -1;
                motor[Lift_Motor2a] = power * -1;
		wait1Msec(1);
	}
	else
	{
		motor[Lift_Motor1] = 0;
		motor[Lift_Motor1a] = 0;
                motor[Lift_Motor2] = 0;
                motor[Lift_Motor2a] = 0;
		mainLiftDone = true;
	}
}

Also, try using a P(proportional) controller for your lift. Example:

static float pid_Kp = 0.2;
static float pidRequestedValue;
task ArmControl()
{
	float pidSCV;
	float pidE;
	float pidD;

	while(true)
	{
		pidSCV = SensorValue[lift_pot_1];

		pidE = pidRequestedValue - pidSCV;

		pidD = (pid_Kp * pidE);

		if(pidD > 15)
		{
			pidD = 127;
		}
		if(pidD < -15)
		{
			pidD = -127;
		}

		motor(LTower) = pidD;
		motor(RTower) = pidD*-1;

		wait1Msec(25);
	}
}


void mainLift (int value)
{
	pidRequestedValue = value;
        if((pidRequstedValue - 30) <= SensorValue[lift_pot_1] <= (pidRequestedValue + 30))
        {
              mainLiftDone = true;
        }
}

With the above, the task takes care of the arm movement, and mainLiftDone is only verified when the lift is within a certain range of values, make them as tight as possible. The task I added is a simple P controller, and better controls movement than your code. Hope this helps!

Thanks all, I’ll try that code you posted at the top.

Just curious, did you see anything other than using ‘motor’ instead of ‘SetMotor’?

I will be disappointed if jpearmans “SmartMotorLib” is the source of my issues.

Thanks for the suggestion to use a proportional controller on the lift, I have been trying for about 3 weeks to get something like that to work and it escapes me how to get it going.

I’ll give it another shot and see what I end up with.

Thanks again!
Mike

Oh. I’ve never used it so I was unaware. You could just replace all the ones I changed with setMotor

Hey gang, still fighting this thing. Got a chance to try the code and I’m still having things run over top of each other.

To eliminate any confusion, this is the exact code:

bool clawDone = false;
void claw(int time, int power)
{
	motor[Claw] = power;
	wait (time);
	motor[Claw] = 0;
	clawDone = true;
}

bool mainLiftDone = false;
void mainLift (int value, int power)
{
	if(SensorValue[lift_pot_1] < value-LIFT_THRESHOLD)
	{
		motor[Lift_Motor1] = power;
		motor[Lift_Motor1a] = power;
		motor[Lift_Motor2] = power;
		motor[Lift_Motor2a] = power;
		wait1Msec(1);
	}
	else if(SensorValue[lift_pot_1] > value+LIFT_THRESHOLD)
	{
		motor[Lift_Motor1] = power * -1;
		motor[Lift_Motor1a] = power * -1;
		motor[Lift_Motor2] = power * -1;
		motor[Lift_Motor2a] = power * -1;
		wait1Msec(1);
	}
	else
	{
		motor[Lift_Motor1] = 0;
		motor[Lift_Motor1a] = 0;
		motor[Lift_Motor2] = 0;
		motor[Lift_Motor2a] = 0;
		mainLiftDone = true;
	}
}

task main()
{
	while(true)
	{

		if(vexRT[Btn8D] == 1)
		{
			claw(1, 30); //claw(int time, int power) -------open claw
			mainLift (1800, 30); //mainLift (int value, int power)------lower lift
			claw(1, -30); //claw(int time, int power)------close claw
			mainLift (2200, 30); //mainLift (int value, int power)------raise lift
		}
	}
}

If ya’ll have any more suggestions I’d be most grateful. I’m just not having any luck here.

Thanks!

Your problem is that mainLift runs only once each time it’s called. It’s exiting after only going through the function once. The Panda person suggested a P controller, which would be better, but your control (which would be bang-bang with hysteresis, I think) should somewhat work. You need to put the three if statements within mainLift in a while loop until mainLiftDone becomes true. Also, you would need to set mainLiftDone to false each time you call it before this loop starts (so putting mainLiftDone = false; before the loop within the mainLift function).

Thanks for the help, that got it working exactly as I was wanting. I do need to figure out the PID piece, it does bounce around a bit, but the steps work as I was wanting.

Thanks again!

Lol panda person

Yay!!! Someone got it!