Thread: WCD vs. Swerve
View Single Post
  #75   Spotlight this post!  
Unread 31-12-2011, 16:45
JamesTerm's Avatar
JamesTerm JamesTerm is offline
Terminator
AKA: James Killian
FRC #3481 (Bronc Botz)
Team Role: Engineer
 
Join Date: May 2011
Rookie Year: 2010
Location: San Antonio, Texas
Posts: 298
JamesTerm is a splendid one to beholdJamesTerm is a splendid one to beholdJamesTerm is a splendid one to beholdJamesTerm is a splendid one to beholdJamesTerm is a splendid one to beholdJamesTerm is a splendid one to beholdJamesTerm is a splendid one to behold
Re: WCD vs. Swerve

Quote:
Originally Posted by Siri View Post
That's really interesting, thanks. We'll work back through the driver movements. I'm told at least part of the pause is in the code, but paying attention to inertia never hurts.
Pause in the code? I think I may throw an idea to you that can help with that! First let me show you my code snip of what I do here:

Code:
void Swerve_Robot::InterpolateThrusterChanges(Vec2D &LocalForce,double &Torque,double dTime_s)
{
	//Now the new UpdateVelocities was just called... work with these intended velocities
	for (size_t i=0;i<4;i++)
	{
		const double IntendedDirection=GetIntendedVelocitiesFromIndex(i+4);
		double SwivelDirection=IntendedDirection;  //this is either the intended direction or the reverse of it
		const Ship_1D &Swivel=m_DrivingModule[i]->GetSwivel();
		const double LastSwivelDirection=Swivel.GetPos_m();
		double DistanceToIntendedSwivel=LastSwivelDirection-SwivelDirection;
		NormalizeRotation(DistanceToIntendedSwivel);
		DistanceToIntendedSwivel=fabs(DistanceToIntendedSwivel);

		if ((DistanceToIntendedSwivel>PI_2) || (SwivelDirection>Swivel.GetMaxRange()) || (SwivelDirection<Swivel.GetMinRange()) )
		{
			SwivelDirection+=PI;
			NormalizeRotation(SwivelDirection);
			double TestIntendedFlipped=IntendedDirection+PI;
			NormalizeRotation(TestIntendedFlipped);

			//If we flipped because of a huge delta check that the reverse position is in range... and flip it back if it exceed the range
			if ((SwivelDirection>Swivel.GetMaxRange()) || (SwivelDirection<Swivel.GetMinRange()) ||
				(TestIntendedFlipped>Swivel.GetMaxRange()) || (TestIntendedFlipped<Swivel.GetMinRange()))
			{
				SwivelDirection+=PI;
				NormalizeRotation(SwivelDirection);
			}
		}
		//Note the velocity is checked once before the time change here, and once after for the current
		//Only apply swivel adjustments if we have significant movement (this matters in targeting tests)
		if ((fabs(LocalForce[0])>1.5)||(fabs(LocalForce[1])>1.5)||(fabs(m_DrivingModule[i]->GetDrive().GetPhysics().GetVelocity()) > 0.05))
			m_DrivingModule[i]->SetIntendedSwivelDirection(SwivelDirection);
		const double IntendedSpeed=GetIntendedVelocitiesFromIndex(i);

		//To minimize error only apply the Y component amount to the velocity
		//The less the difference between the current and actual swivel direction the greater the full amount can be applied
		double VelocityToUse=cos(DistanceToIntendedSwivel)*IntendedSpeed;

		m_DrivingModule[i]->SetIntendedDriveVelocity(VelocityToUse);
		m_DrivingModule[i]->TimeChange(dTime_s);

		const double CurrentVelocity=m_DrivingModule[i]->GetDrive().GetPhysics().GetVelocity();
		const double CurrentSwivelDirection=Swivel.GetPos_m();
		//if (i==0)
		//	DOUT4("S= %f %f V= %f %f",CurrentSwivelDirection,SwivelDirection,CurrentVelocity,VelocityToUse);

		//Now to grab and update the actual swerve velocities
		//Note: using GetIntendedVelocities() is a lesser stress for debug purposes
		#if 1
		m_Swerve_Robot_Velocities.Velocity.AsArray[i+4]=CurrentSwivelDirection;
		m_Swerve_Robot_Velocities.Velocity.AsArray[i]=CurrentVelocity;
		#else
		m_Swerve_Robot_Velocities=GetIntendedVelocities();
		#endif
	}

	__super::InterpolateThrusterChanges(LocalForce,Torque,dTime_s);
}
Check out this line in particular:

Code:
		//To minimize error only apply the Y component amount to the velocity
		//The less the difference between the current and actual swivel direction the greater the full amount can be applied
		double VelocityToUse=cos(DistanceToIntendedSwivel)*IntendedSpeed;
Let me explain this line here... Imagine if you will the one scene where you where strafing us and then want to move folward... Let's assume for the sake of arguement the driver was pushing staight forard (this will help visualize the solution)... During each frame that transitions the angle from 90 to 0 degrees (where 0 is forward)... ANY Y component of the vector will be executed with a tradeoff of minimal error. In this case the robot would slightly arc on the X component to give you the most Y you can have during the transition. It should be also noted that it also will determine the correct + or - direction of the wheels as well (no branching Yay!). I hope this makes sense... In my demo when I strafe and rotate at the same time... the key for this success is this line of code where every opportunity to fulfill the x component of the vector will happen.


Quote:
Originally Posted by Siri View Post
James: Thanks, I was hoping you had the video to share. We don't have any championship video. Could I try to find a way to get the higher resolution version?
I will talk with my friend Jeremy tonight about this. I did resubmit the wmv file with a lower 320x240 and found that framerate is much better, so if you have the 640x480... go back to the link and try it again... It looks good on a phone too.

I'll keep you posted... I WILL get this to you somehow!
Reply With Quote