Algebrai c l oop error - помогите исправить ложную зависимость - PullRequest
1 голос
/ 04 мая 2020

tldr: почему мой завод помечен как прямой и как мне отменить эту маркировку?

Я создал завод в Drake, который принимает входное напряжение phi и использует это плюс состояние системы Lam для вычисления своих производных Lam_d. Затем я подключил систему к FittedValueIteration, чтобы сгенерировать свою политику управления ею. Итерация значения успешно сгенерировала политику (и после проверки она выглядит очень разумной), но когда я пытаюсь подключить ее к моей системе с помощью построителя диаграмм, я получаю следующее сообщение, указывающее, что у меня есть прямая связь:

RuntimeError: Reported algebraic loop detected in DiagramBuilder:
  InputPort[0] (phi) of System ::drake/pydrake/(anonymous)/Impl@000000000648eec0 (Impl<double>::PyLeafSystemBase<drake::pydrake::(anonymous)::Impl<double>::LeafSystemPublic>) is direct-feedthrough to
  OutputPort[0] (Lam) of System ::drake/pydrake/(anonymous)/Impl@000000000648eec0 (Impl<double>::PyLeafSystemBase<drake::pydrake::(anonymous)::Impl<double>::LeafSystemPublic>) is connected to
  InputPort[0] (u0) of System ::drake/systems/BarycentricMeshSystem@0000000005c6d300 (BarycentricMeshSystem<double>) is direct-feedthrough to
  OutputPort[0] (y0) of System ::drake/systems/BarycentricMeshSystem@0000000005c6d300 (BarycentricMeshSystem<double>) is connected to
  InputPort[0] (phi) of System ::drake/pydrake/(anonymous)/Impl@000000000648eec0 (Impl<double>::PyLeafSystemBase<drake::pydrake::(anonymous)::Impl<double>::LeafSystemPublic>)

Я считаю, что в vi_policy действительно есть прямая связь (barycentri c me sh, на которую ссылаются в сообщении об ошибке), так как она просто принимает состояние и выдает вывод на основе который. Моя установка, однако, использует вход контроллера для создания ускорения, поэтому я не понимаю, почему это помечено. Мой завод показан ниже для справки:

class DEAContinuousSys(LeafSystem):
  def __init__(self):
    LeafSystem.__init__(self)

    self.DeclareContinuousState(2) # two state variables: lam, lam_d
    self.DeclareVectorOutputPort('Lam', BasicVector(2), self.CopyStateOut) # two outputs: lam_d, lam_dd
    self.input_port = self.DeclareVectorInputPort('phi', BasicVector(1)) 

  def DoCalcTimeDerivatives(self, context, derivatives): 
    Lam = context.get_continuous_state_vector().get_value() # get state, cast as regular array
    phi = self.input_port.Eval(context)
    Lam_d = DEA.dynamics(Lam, None, phi) # derive acceleration (no timestep required)
    derivatives.get_mutable_vector().SetAtIndex(0, Lam_d[0]) # set velocity
    derivatives.get_mutable_vector().SetAtIndex(1, Lam_d[1]) # set acceleration

  def CopyStateOut(self, context, output):
    Lam = context.get_continuous_state_vector().CopyToVector()
    output.SetFromVector(Lam)

Я решил, что это прямое сквозное уведомление было ошибочным, но у меня возникли проблемы с анализом документации, чтобы исправить эту проблему. Итак, я все еще пытаюсь выяснить:

  1. Почему это было помечено как прямая передача?
  2. Как мне добавить билет в указать, что это не прямой проход? Есть ли где-нибудь хороший пример, на который я могу сослаться?

edit: перечитав документацию, я вижу, что ответ на 1. состоит в том, что по умолчанию все LeafSystems будут установлены как прямые -Проход, чтобы избежать случайных петель. Если бы мое растение представляло собой простую комбинацию символов c выражений, его можно было бы правильно интерпретировать.

1 Ответ

2 голосов
/ 04 мая 2020

По умолчанию объявления OutputPort s зависят от всех источников, включая входные порты. Кажется, ваш выходной порт зависит только от вашего непрерывного состояния. Вы можете изменить свое объявление, чтобы четко указать это. Это должно убрать вашу алгебру c l oop go.

Попробуйте:

self.DeclareVectorOutputPort('Lam', BasicVector(2), self.CopyStateOut, 
                             prerequisites_of_calc=set([self.xc_ticket()]))

(Я не на 100% использую орфографию pydrake, но я бы до сих пор кладут на это деньги.)

...