如何在CAPL中将信号用作函数参数

3
我可以帮助您进行翻译。需要翻译的内容与IT技术相关,将"Original Answer"翻译为"最初的回答"。下面是您需要翻译的内容:

我想在CAPL中编写一个函数,该函数接收一个信号并利用信号值、信号系数和信号偏移来计算物理值。

以下是简单网关的工作方式:

message CAN1.myMessage1 myMessage1 = {DIR = RX};//message from the database
message CAN2.myMessage2 myMessage2 = {DIR = TX};//another message from the database

on message CAN1.*
{
   if(this.id == myMessage1.id)
   {
      myMessage1 = this;
      myMessage2.mySignalB = myMessage1.mySignalA * myMessage1.mySignalA.factor + myMessage1.mySignalA.offset;
   }
}

最初的回答是我正在尝试做以下事情:

这就是我要做的:

...
on message CAN1.*
{
   if(this.id ==myMessage1.id)
   {
      myMessage1 = this;
      myMessage2.mySignalB = PhysicalValue(myMessage1.mySignalA);
   }
}

double PhysicalValue(signal * s)
{
  return s*s.factor+s.offset;
}

这段代码有两个问题:
第一,当我将信号作为参数传递时,编译器会提示类型不匹配。第二个问题是,在函数内部无法识别属性(因子和偏移量)。
这些问题可能与CAPL的奇怪面向对象但不完全面向对象的特性有关。可以直接访问信号的值,但它也具有属性?

最初的回答:

int rawValue = myMessage1.mySignalA;

如果您熟悉C语言,您可能会说我的问题在于我在函数中指定了一个指针,但我没有将指针传递给它。但在CAPL中,没有指针,*只是代表任何东西。 如果没有*,我将需要使用特定的信号,这将违背函数的目的。
编辑: 现在我已经找到了属性.phys,它完全可以实现我的演示功能。
double physValue = myMessage1.mySignalA.phys;

虽然这样已经让我的代码变得更短了,但我还需要对多个信号执行其他操作,所以能够将信号用作函数参数仍然很有用。

"Original Answer" 翻译成 "最初的回答"


请展示一下你的代码好吗?首先,message是什么?它是一个CAN消息吗?我从来没有见过可以像这样访问CAN消息的信号。此外,当你直接在CAPL中访问信号值时,你已经得到了物理值,不需要自己计算。 - MSpiller
我希望我所做的修改能够澄清问题。 - TomMaier
我猜on signal事件不适合你的目的,对吗?然而,我不明白为什么。因为你想要通用化吗?如果是这样,你可以使用系统变量来模拟任何所需的信号,并将其作为事件的触发器。我从未尝试过,所以这只是纯粹的想象。告诉我你的想法。 - Daemon Painter
我考虑过使用系统变量,但我得出的结论是这不会改变问题,因为我仍然需要单独处理每个信号。这也是我不能使用on signal的原因。当然,我可以用on signal替换on message + id check,但那意味着要写很多额外的代码。 - TomMaier
2个回答

2
你可以做的是这样的:

double PhysicalValue(signal * s)
{
  // access signal by prepending a $
  return $s.phys;
}

像这样调用。
on message CAN1.*
{
   if(this.id ==myMessage1.id)
   {
      myMessage1 = this;
      myMessage2.mySignalB = PhysicalValue(CAN1::myMessage1::mySignalA);
   }
}

即,当您调用函数时,必须提供信号的限定名称(使用冒号而不是点)。据我所知,不能使用myMessage1.mySignalA,因为信号本身不是CAPL数据类型。
除此之外,您可能需要重新考虑是否真的应该使用on message,而应该切换到on signal。无论使用哪个消息发送信号值,都由CANoe的信号服务器处理。

感谢你的出色答案。 不幸的是,我得到了一个错误:“在当前上下文(CANalyzer、Analyze、Test…)中不允许使用面向信号的CAPL。” 所以我猜$符号与CANalyzer不兼容? - TomMaier
看起来是这样的。我一直在使用CANoe,并没有意识到CANalyzer有这个限制。 - MSpiller

0
请注意,CANoe已经有一个函数可以完全实现你想要做的事情(乘以因子并加上偏移量)。它被称为getSignal
on message CAN1.*
{
   if(this.id == myMessage1.id)
   {
      myMessage2.mySignalB = getSignal(myMessage1::mySignalA);
   }
}

偏移量和因子在例如DBC文件中定义。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接