手把手教做无人驾驶算法(二十六)--基于终端约束的MPC 控制

4 篇文章 1 订阅

关于MPC终端约束问题,其实就是稳定性与可行性的分析,欢迎感兴趣的一起交流探讨,如有错误,还请指正,不胜感激。

基于终端约束的MPC控制,理论部分可以参考资料:

【Linear MPC入门】Model Predictive Control Algorithm, Feasibility and Stability - 知乎

这里,终端约束数据可以用数据驱动来代替,这样就可以把MPC与数据驱动相结合起来,但是好处不仅仅是为了与数据驱动联合,终端约束有什么好处呢?上面的参考资料也给出了参考。

对于一般MPC而言,相当于零点为终点,不过,使用Zero Terminal Constraint是非常苛刻的,导致可行域减少了很多。同时,MPC的预测的步数N越少,可行域也越少。

对于可行域使用凸多面体表示,如上图:

function [ invariantGoalSet ] = computeInvariantGoalSet( A, B, Q, R )

[K,~,~] = dlqr(A,B,Q,R);

Acl = A-B*K;
w_max = 0.05;
W = Polyhedron([w_max w_max; w_max -w_max; -w_max -w_max; -w_max w_max]);

X{1} = zeros(size(Acl,1),1); % Initialize the set
for i = 1:10000
    Set = Acl*X{i} + W; % Propagate the uncertanty
    Set.minHRep() % Compute minimal representation
    Set.minVRep() % Compute minimal representation
    X{i+1} = Set;
    % Check if the algorithm has covnerged 
    if i > 1
        if (X{i+1}.contains(X{i})) && (X{i}.contains(X{i+1}))
            invariantGoalSet = X{i+1}; % Set invaraint to the current iterate
            disp(['Invariant set computed in i = ',num2str(i),' iterations'])            
            break
        end
    end
end

end

 下面给出一个例子:

这里,首先使用MPC去解除有效的解,即状态值,输入值,同时使用这些量可以计算出状态量,形成安全集,使用这些安全集SS作为终端约束以及代价约束,核心部分代码如下:


	def addTrajectory(self, x, u):
		# Add the feasible trajectory x and the associated input sequence u to the safe set
		self.SS.append(copy.copy(x))
		self.uSS.append(copy.copy(u))

		# Compute and store the cost associated with the feasible trajectory
		cost = self.computeCost(x, u)
		self.Qfun.append(cost)

		# Initialize zVector
		self.zt = np.array(x[self.ftocp.N])

		# Augment iteration counter and print the cost of the trajectories stored in the safe set
		self.it = self.it + 1
		print("Trajectory added to the Safe Set. Current Iteration: ", self.it)
		print("Performance stored trajectories: \n", [self.Qfun[i][0] for i in range(0, self.it)])

	def computeCost(self, x, u):
		# Compute the cost in a DP like strategy: start from the last point x[len(x)-1] and move backwards
		for i in range(0,len(x)):
			idx = len(x)-1 - i
			if i == 0:
				cost = [np.dot(np.dot(x[idx],self.Q),x[idx])]
			else:
				cost.append(np.dot(np.dot(x[idx],self.Q),x[idx]) + np.dot(np.dot(u[idx],self.R),u[idx]) + cost[-1])
		
		# Finally flip the cost to have correct order
		return np.flip(cost).tolist()

上面为计算SS安全集以及代价值

# Terminal Constraint if SS not empty --> enforce the terminal constraint
		if SS is not None:
			constr += [SS * lambVar[:,0] == x[:,self.N], # Terminal state \in ConvHull(SS)
						np.ones((1, SS.shape[1])) * lambVar[:,0] == 1, # Multiplies \lambda sum to 1
						lambVar >= 0] # Multiplier are positive definite

		# Cost Function
		cost = 0
		for i in range(0, self.N):
			# Running cost h(x,u) = x^TQx + u^TRu
			#ost += quad_form(x[:,i], self.Q) + norm(self.R**0.5*u[:,i])**2
			# cost += quad_form(x[:,i], self.Q) + quad_form(u[:,i], self.R)
			cost += norm(self.Q**0.5*x[:,i])**2 + norm(self.R**0.5*u[:,i])**2

		# Terminal cost if SS not empty
		if SS is not None:
			cost += Qfun[0,:] * lambVar[:,0]  # It terminal cost is given by interpolation using \lambda
		else:
			cost += norm(self.Q**0.5*x[:,self.N])**2 # If SS is not given terminal cost is quadratic

这里代码是终端约束以及终端代价约束。

没有终端约束的轨迹:

带有终端约束的轨迹:

 具体代码地址,这个代码为python 写的:

MPC/LinearLMPC at main · caokaifa/MPC · GitHub

  • 1
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 学习DSP(数字信号处理)是一个复杂又有趣的过程,有许多资源可供选择。而其中一种资源是基于TMS320C55x的光盘资料,可以帮助你逐步学习和掌握DSP的技能。下面是我对使用这种资料进行学习的建议: 首先,确保你具备一定的数学基础,特别是在信号处理和算法方面。这将帮助你更好地理解DSP的原理和算法。 光盘资料通常提供了一个系统的学习路径,从基础知识开始逐步深入。按照这样的顺序进行学习可以确保你不会遗漏任何重要的概念。 光盘通常提供了一些示例代码以及对应的解释。通过仔细阅读和理解这些代码,你可以学习到如何使用TMS320C55x的指令集和工具来实现各种信号处理算法。 尝试自己编写一些简单的代码来实现光盘资料中的示例算法。通过自己动手实践,你能更好地掌握这些概念和技能。 如果你遇到困难或者有任何疑问,不要犹豫,寻求帮助。你可以通过光盘资料提供的论坛或者社区向其他学习者和专业人士请。此外,还可以参考其他书籍、程和在线资源,进一步加深理解。 最后,保持耐心和坚持。学习DSP需要时间和努力,不要轻易放弃。通过光盘资料和其他学习资源,你会逐渐掌握TMS320C55x的使用和DSP的核心概念。 总之,通过使用基于TMS320C55x的光盘资料,你可以以系统和有序的方式学习DSP。遵循资料提供的学习路径,尝试编写代码,寻求帮助,并保持耐心和坚持,你将能够掌握这一令人激动的技能。 ### 回答2: 学习DSP (数字信号处理) 需要具备一定的理论基础和实践经验。借助光盘资料上提供的基于TMS320C55x的学内容,我将简要介绍手把手学习DSP的步骤和过程。 首先,根据光盘资料提供的学介绍,了解TMS320C55x的基本原理和架构。该芯片是一种高性能的DSP处理器,具有出色的运算能力和多媒体处理功能。理解其体系结构以及寄存器结构是学习的第一步。 接下来,光盘资料上会提供一些示例代码和实验项目。这些代码和项目是基于TMS320C55x的典型应用案例,可以帮助我们更好地理解和巩固所学知识。通过仔细分析这些代码和项目,我们可以学习如何设计和实现DSP算法。 然后,我们可以开始手动编写程序。光盘资料上应该会提供编程工具和开发环境。使用这些工具和环境,我们可以编写和调试自己的DSP程序。在此过程中,需要逐步学习DSP算法和优化技巧,以提高程序的性能和效率。 此外,光盘资料上可能还包含一些实验指导。通过这些实验,我们可以通过实际操作来加深对DSP原理和应用的理解。在实验过程中,要注意记录和分析实验结果,从而不断优化和改进自己的程序。 最后,持续学习和实践是掌握DSP的关键。光盘资料可能不会涵盖所有的内容,因此我们需要通过阅读材、参考资料和在线资源来持续学习。同时,通过自己的实践和项目经验,我们可以掌握更深入的DSP知识和技能。 总之,学习DSP是一个逐步深入的过程,只有通过理论学习和实践经验的结合,才能真正掌握这一领域的知识和技能。光盘资料提供了一个全面而系统的学习框架,但我们自身的努力和坚持才是学习成功的关键。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值