如何在 Dymos 中将数量的积分指定为目标

Posted

技术标签:

【中文标题】如何在 Dymos 中将数量的积分指定为目标【英文标题】:How to specify integration of a quantity as an objective in Dymos 【发布时间】:2022-01-19 21:38:46 【问题描述】:

我正在实施 Bryson-Denham 问题。目标是:

$J=\frac12\int_0^1u^2\left(t\right)dt$

在 Dymos 的文档中,所有解释和示例都将目标值声明为 loc=initial 或 loc=final 处的标量。我找不到任何使用随时间积分作为目标函数的示例。这可能吗?我该如何实现?

仅供参考,Bryson-Denham 问题在此页面中得到了很好的解释: https://www.gpops2.com/Examples/Bryson-Denham.html

【问题讨论】:

Dymos 将任何时间积分的数量视为一种状态。由于目标 J 与其他状态在同一区间内积分,因此我们可以将其添加为状态本身。 Rob,在我看到你的评论和 Justin 的详细解释后,我想我对 Dymos 的工作原理有了一个清晰的认识。非常感谢您的回答。 因为这是一个非常经典的问题,我已将其添加到此处文档中的示例中:openmdao.github.io/dymos/examples/bryson_denham/… 【参考方案1】:

Dymos 会整合你给它的任何状态。在这种情况下,您需要为 J 添加一个状态,然后为它计算一个状态率 --- J_dot。

import openmdao.api as om 
import dymos as dm

class BrysonDedhamODE(om.ExplicitComponent):


    def initialize(self):
        self.options.declare('num_nodes', types=int)

    def setup(self):
        nn = self.options['num_nodes']

        # static parameters
        self.add_input('x', shape=nn)
        self.add_input('v', shape=nn)
        self.add_input('u', shape=nn)
        self.add_input('J', shape=nn)



        # state rates
        self.add_output('x_dot', shape=nn, tags=['dymos.state_rate_source:x'])
        self.add_output('v_dot', shape=nn, tags=['dymos.state_rate_source:v'])
        self.add_output('J_dot', shape=nn, tags=['dymos.state_rate_source:J'])

        # Ask OpenMDAO to compute the partial derivatives using complex-step
        # with a partial coloring algorithm for improved performance, and use
        # a graph coloring algorithm to automatically detect the sparsity pattern.
        self.declare_coloring(wrt='*', method='cs')



    def compute(self, inputs, outputs):

        v, u, j = inputs["v"], inputs["u"], inputs["J"]

        outputs['x_dot'] = v        
        outputs['v_dot'] = u        
        outputs['J_dot'] = 0.5*u**2


p = om.Problem()

p.driver = om.pyOptSparseDriver()
p.driver.options['optimizer'] = 'SLSQP'
p.driver.declare_coloring()

traj = p.model.add_subsystem('traj', dm.Trajectory())

transcription = dm.Radau(num_segments=10, order=3, compressed=True)
phase0 = dm.Phase(ode_class=BrysonDedhamODE, transcription=transcription)

traj.add_phase('phase0', phase0)


phase0.set_time_options(fix_initial=True, fix_duration=True)

phase0.set_state_options("x", fix_initial=True, fix_final=True, lower=0, upper=2)
phase0.set_state_options("v", fix_initial=True, fix_final=True, lower=-2, upper=2)
phase0.set_state_options("J", fix_initial=False, fix_final=False,lower=-10, upper=10)

phase0.add_control('u', lower=-10, upper=10)
phase0.add_path_constraint('x', upper=1/9.)

phase0.add_objective('J', loc="final")

p.setup()

#initial conditions
p['traj.phase0.states:x'] = phase0.interp('x', [0,0])
p['traj.phase0.states:x'] = phase0.interp('x', [0,0])
p['traj.phase0.states:v'] = phase0.interp('v', [1,-1])
p['traj.phase0.t_duration'] = 1
p['traj.phase0.t_initial'] = 0

dm.run_problem(p, make_plots=True)

【讨论】:

贾斯汀在这里的回答很好,尽管您可能想为 J 指定 fix_initial=True 并将初始值设置为零。此外,您可以将'u' 指定为'v' 的rate_source,并将'v' 指定为'x' 的rate_source。在这种情况下,ODE 组件只需要计算J_dot 贾斯汀,非常感谢!这个答案真的很有帮助! 也感谢您提供额外的 cmets,Rob。

以上是关于如何在 Dymos 中将数量的积分指定为目标的主要内容,如果未能解决你的问题,请参考以下文章

java - 如何在java中将特定数量的线程限制为同步块

如何在目标 c 中将 NSString 转换为 NSDictionary?

如何在目标 C 中将字符串转换为整数? [复制]

如何在目标 C 中将 NSInteger 值转换为 int 值? [复制]

如何在目标 C 中将 QLPreviewController 添加为子视图

如何在目标 c 中将 PFFILE 设置为本地 UIImage