⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 apfclass.java

📁 采用PCI1020芯片控制三个电机
💻 JAVA
字号:
package cn.com.yuzhiqiang.pcimotor;

public class APFClass {
	private static final double WHEELBASE = 3;// 前后轮距单位为米

	private static final double RWTOFDISTANCE = 3.5;

	private static final double HALFWIDTH = 1;

	private static final double Ks = 1.2;

	private static final double Db = 80;// 边界阻力用 雷达扫描边界距离

	private static final double ACCELERATION = -2;// m/s2

	private static final double VMAX = 2;// 机器人最高限速m

	private static final double Kv = 0.8;

	// private static final double PI=3.1415926;

	// 对曲率半径和角度的正负约定 右转都为正 左转为负 统一为弧度
	private static final double DriveMaxAngle = Math.toRadians(40);// 40度

	private static final double DriveMinAngle = Math.toRadians(-40);// -40度
																	// 驾驶角的正负界限

	private static double DriveAngle;

	private static double DriveV;

	// private static double PrincipalAxisAngle;// 主轴角度

	// private static double RearCurRadius; // 后轮曲率半径

	// private static double CenterCurRadius; // 中心曲率半径

	private static double Ds = Ks * HALFWIDTH;

	private static double Length_ICR1, Angle_ICR1;

	private static double Length_ICR2, Angle_ICR2;

	private static double D1p, D2p;

	private static double UppLimAngle_Resistance, LowLimAngle_Resistance;// 阻力角范围

	private static double Fp_Resistance;// P点阻力

	protected static double Fb_Resistance = 1 / Math.sqrt(Db * Db - Ds * Ds);// 边界点阻力

	private static double Length_Object, Angle_Object = 0;// 目标点长度和角度

	private static double F_CurrentPass;// 当前视场的通行函数

	private static double Angle_CurrentPass;// 当前视场驾驶角度

	private static double[] Length_Polar = { 10100, 1010, 1010, 1010, 1020,
			1060, 1040, 1050, 1040, 1050, 1000, 1020, 1000, 1020, 1040, 1050,
			1040, 1040, 1030, 1010, 1019, 8011, 8070, 8029, 8246, 8054, 10200,
			23900, 241, 242, 243, 244, 246, 247, 248, 250, 251, 252, 254, 255,
			256, 258, 259, 261, 262, 263, 265, 266, 268, 269, 270, 273, 274,
			276, 278, 279, 282, 284, 286, 287, 289, 293, 295, 297, 299, 302,
			304, 307, 309, 312, 315, 318, 321, 324, 327, 330, 329, 327, 324,
			322, 319, 317, 315, 313, 311, 309, 307, 305, 303, 301, 300, 297,
			296, 295, 293, 291, 289, 288, 286, 285, 283, 282, 281, 280, 278,
			277, 275, 274, 273, 272, 271, 270, 269, 268, 266, 266, 266, 267,
			268, 266, 269, 269, 268, 267, 267, 266, 264, 263, 261, 260, 260,
			260, 260, 260, 261, 259, 259, 258, 258, 257, 255, 255, 254, 251,
			248, 248, 247, 246, 246, 246, 247, 247, 246, 247, 247, 246, 246,
			246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246,
			246, 247, 247, 247, 247, 247, 248, 248, 248, 250, 250, 250, 251,
			251, 252, 252, 253, 253, 254, 254, 254, 255, 256, 256, 257, 258,
			258, 259, 259, 260, 261, 262, 263, 264, 264, 266, 266, 267, 268,
			269, 270, 270, 272, 273, 275, 275, 276, 278, 279, 281, 282, 284,
			285, 8191, 288, 8191, 289, 8191, 8191, 8191, 8191, 8191, 8191,
			8191, 8191, 8191, 8191, 8191, 8191, 1700, 8191, 1400, 8191, 1708,
			1978, 1799, 1489, 1888, 1656, 1656, 1688, 1633, 164, 173, 160, 188,
			167, 157, 168, 144, 178, 154, 174, 125, 153, 143, 145, 8191, 143,
			8191, 125, 8191, 133, 8191, 8191, 8191, 8191, 8191, 8191, 8191,
			8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 1709, 1899,
			1499, 1389, 1245, 1143, 1242, 1152, 1154, 1052, 9554, 9550, 855,
			855, 855, 955, 855, 955, 855, 955, 933, 833, 954, 845, 900, 1006,
			966, 1155, 1266, 1366, 1266, 1266, 1366, 1166, 1066, 1066, 1156,
			1178, 1189, 1089, 1088, 1099, 1388, 1288, 1288, 1388, 988, 1288,
			1288, 1188, 200, 1100, 290, 1200, 320, 1030, 310, 1079, 329, 249,
			320, 310, 320, 320, 320, 310, 330, 320, 339, 310, 329, 329 };// 正式程序中应为引用
																			// 0.5度激光雷达传一个数

	// 单位为厘米 正式计算时变为米 调试时用

	// double []Length_Polar={101 101 101 101 102 106 104 105 104 105 100 102
	// 100
	// 102 104 105 104 104 103 101 101 100 102 101 101 102 102 239 241 242 243
	// 244
	// 246 247 248 250 251 252 254 255 256 258 259 261 262 263 265 266 268 269
	// 270
	// 273 274 276 278 279 282 284 286 287 289 293 295 297 299 302 304 307 309
	// 312
	// 315 318 321 324 327 330 329 327 324 322 319 317 315 313 311 309 307 305
	// 303
	// 301 300 297 296 295 293 291 289 288 286 285 283 282 281 280 278 277 275
	// 274
	// 273 272 271 270 269 268 266 266 266 267 268 266 269 269 268 267 267 266
	// 264
	// 263 261 260 260 260 260 260 261 259 259 258 258 257 255 255 254 251 248
	// 248
	// 247 246 246 246 247 247 246 247 247 246 246 246 246 246 246 246 246 246
	// 246
	// 246 246 246 246 246 246 247 247 247 247 247 248 248 248 250 250 250 251
	// 251
	// 252 252 253 253 254 254 254 255 256 256 257 258 258 259 259 260 261 262
	// 263
	// 264 264 266 266 267 268 269 270 270 272 273 275 275 276 278 279 281 282
	// 284
	// 285 8191 288 8191 289 8191 8191 8191 8191 8191 8191 8191 8191 8191 8191
	// 8191
	// 8191 17 8191 14 8191 17 19 17 14 18 16 16 16 16 16 17 16 18 16 15 16 14
	// 17 15
	// 17 12 15 14 14 8191 14 8191 12 8191 13 8191 8191 8191 8191 8191 8191 8191
	// 8191 8191 8191 8191 8191 8191 8191 8191 8191 17 18 14 13 12 11 12 11 11
	// 10 9
	// 9 8 8 8 9 8 9 8 9 9 8 9 8 9 10 9 11 12 13 12 12 13 11 10 10 11 11 11 10
	// 10 10
	// 13 12 12 13 9 12 12 11 20 11 29 12 32 13 31 17 32 24 32 31 32 32 32 31 33
	// 32
	// 33 31 32 32
	// };

	// private static double []Angle_Polar=new double[]; //数据从-pi/2到pi/2
	private static double[] ULAngle = new double[361];// 各阻力角上限和下限

	private static double[] LLAngle = new double[361];

	protected static double[] F_SingleResistance = new double[361];//正式程序设为私有 下同

	protected static double[] Fr_Resistance = new double[361];// 总阻力

	protected static double[] F_Attraction = new double[361];// 引力

	protected static double[] F_Pass = new double[361];// 通行函数
	// 注意所有的角度单位统一为弧度

	public APFClass() {

	}

	protected static void CalICR() {

		// 调试用
		/*
		 * for(int i=0;i<361;i++){ Length_Polar[i]=8100; }
		 * Length_Polar[100]=3500; Length_Polar[105]=4500;//调试结束
		 */
		// 计算ICR1和ICR2的极坐标
		Length_ICR1 = -RWTOFDISTANCE
				/ Math.sin(Math.atan(RWTOFDISTANCE * Math.tan(DriveMinAngle)
						/ WHEELBASE));// 假设左转角度都小于0
		Angle_ICR1 = Math.atan(RWTOFDISTANCE * Math.tan(DriveMinAngle)
				/ WHEELBASE)
				- Math.PI / 2;
		Length_ICR2 = RWTOFDISTANCE
				/ Math.sin(Math.atan(RWTOFDISTANCE * Math.tan(DriveMaxAngle)
						/ WHEELBASE));
		Angle_ICR2 = Math.atan(RWTOFDISTANCE * Math.tan(DriveMaxAngle)
				/ WHEELBASE)
				+ Math.PI / 2;
	}

	// 计算单个点阻力 有问题!!
	protected static void CalSingleResistance(double pdistance, double pangle) {
		// 计算ICR1和ICR2的极坐标
		/*
		 * Length_ICR1 = RWTOFDISTANCE / Math.sin(Math.atan(RWTOFDISTANCE *
		 * Math.tan(DriveMinAngle) / WHEELBASE)); Angle_ICR1 =
		 * Math.atan(RWTOFDISTANCE * Math.tan(DriveMinAngle) / WHEELBASE) -
		 * Math.PI / 2; Length_ICR2 = RWTOFDISTANCE /
		 * Math.sin(Math.atan(RWTOFDISTANCE * Math.tan(DriveMaxAngle) /
		 * WHEELBASE)); Angle_ICR2 = Math.atan(RWTOFDISTANCE *
		 * Math.tan(DriveMaxAngle) / WHEELBASE) - Math.PI / 2;
		 */
		// CalICR();
		// double D1p,D2p,Fp_Resistance,LowLimAngle,UppLimAngle;
		D1p = Math.sqrt(Length_ICR1 * Length_ICR1 + pdistance * pdistance - 2
				* Length_ICR1 * pdistance * Math.cos(Angle_ICR1 - pangle));
		D2p = Math.sqrt(Length_ICR2 * Length_ICR2 + pdistance * pdistance - 2
				* Length_ICR2 * pdistance * Math.cos(Angle_ICR2 - pangle));

		// 计算P点阻力角范围
		if (Math.abs(D1p - Length_ICR1) > Ds)
			LowLimAngle_Resistance = pangle - Math.asin(Ds / pdistance);
		else
			LowLimAngle_Resistance = -Math.PI / 2;
		if (Math.abs(D2p - Length_ICR2) > Ds)
			UppLimAngle_Resistance = pangle + Math.asin(Ds / pdistance);
		else
			UppLimAngle_Resistance = Math.PI / 2;

		// 计算p点阻力

		Fp_Resistance = 1 / Math.sqrt(pdistance * pdistance - Ds * Ds);
		/*
		 * if ((pangle >= LowLimAngle_Resistance) && (pangle <=
		 * UppLimAngle_Resistance)) Fp_Resistance = 1 / Math.sqrt(pdistance *
		 * pdistance - Ds * Ds);//防止p点距离过小 平方根里为负 else Fp_Resistance = 0;
		 */

	}

	// 计算每个角度阻力和作用域范围 并赋值
	protected static void SetPResistance() {
		// double
		// D1p,D2p,Fp_Resistance,LowLimAngle_Resistance,UppLimAngle_Resistance;
		CalICR();
		for (int i = 0; i < 361; i++) {
			CalSingleResistance(Length_Polar[i] / 100, -Math.PI / 2
					+ Math.toRadians(i * 0.5));//
			ULAngle[i] = UppLimAngle_Resistance;
			LLAngle[i] = LowLimAngle_Resistance;
			F_SingleResistance[i] = Fp_Resistance;
		}
	}

	// 计算每个角度总阻力 程序算法待改进 太耗时 有问题!!!!
	protected static void CalTotalResistance() {
		double dMaxF_temp;
		SetPResistance();
		for (int i = 0; i < 361; i++) {
			dMaxF_temp = F_SingleResistance[i];
			for (int j = 0; j < 361; j++) {
				if ((LLAngle[j] <= Math.toRadians(i * 0.5) - Math.PI / 2)
						&& (ULAngle[j] >= -Math.PI / 2
								+ Math.toRadians(i * 0.5))) {
					if (dMaxF_temp < F_SingleResistance[j])
						dMaxF_temp = F_SingleResistance[j];
				}

			}
			if (dMaxF_temp < Fb_Resistance)
				dMaxF_temp = Fb_Resistance;// 和边界阻力比较
			Fr_Resistance[i] = dMaxF_temp;

		}
	}

	// 计算每个角度的引力
	protected static void CalAttraction() {
		for (int i = 0; i < 361; i++) {
			if (Math.abs(-Math.PI / 2 + Math.toRadians(i * 0.5 - Angle_Object)) < Math.PI / 2)
				F_Attraction[i] = Math.cos(-Math.PI / 2
						+ Math.toRadians(i * 0.5 - Angle_Object));
			else
				F_Attraction[i] = 0;
		}
	}

	// 计算通行函数
	protected static void PassFunction() {
		double dMaxFpass, s;
		CalTotalResistance();
		CalAttraction();
		for (int i = 0; i < 361; i++) {
			F_Pass[i] = F_Attraction[i] / Fr_Resistance[i];
		}
		dMaxFpass = F_Pass[0];// 假设第一个通行函数大
		s = 0;
		for (int i = 1; i < 361; i++) {
			if (dMaxFpass < F_Pass[i]) {
				dMaxFpass = F_Pass[i];
				s = i;
			}
		}
		F_CurrentPass = dMaxFpass;
		Angle_CurrentPass = Math.toRadians(s * 0.5) - Math.PI / 2;
	}

	// 决策输出函数
	protected static void OutputFunction() {
		double dDriveAngleM, dDriveV;
		int s;
		dDriveAngleM = Math.atan(WHEELBASE * Math.tan(Angle_CurrentPass)
				/ RWTOFDISTANCE);
		if (dDriveAngleM < DriveMinAngle)
			DriveAngle = DriveMinAngle;
		if ((dDriveAngleM >= DriveMinAngle) && (dDriveAngleM <= DriveMaxAngle))
			DriveAngle = dDriveAngleM;
		if (dDriveAngleM > DriveMaxAngle)
			DriveAngle = DriveMaxAngle;
		// 驾驶速度
		s = (int) ((Angle_CurrentPass + Math.PI / 2) / Math.toRadians(0.5));
		dDriveV = Kv * Math.sqrt(-2 * ACCELERATION / Fr_Resistance[s]);
		DriveV = Math.min(dDriveV, VMAX);

	}

	// 读出驾驶角 转化为度
	public static double ReadDriveAngle() {
		return Math.toDegrees(DriveAngle);
	}

	// 读驾驶速度
	public static double ReadDriveV() {
		return DriveV;
	}
//	读当前视场通行函数
	public static double ReadCurrentPass(){
		return F_CurrentPass;
	}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -