【问题标题】:Assigning the function output to a variable将函数输出分配给变量
【发布时间】:2017-09-28 10:08:23
【问题描述】:

我有一个函数,它返回一个名为“a”的 4x2 矩阵的地址。 此函数计算内部“a”矩阵的元素并返回矩阵的地址。当我使用该函数时,我想将其输出分配给一个名为“a1”的矩阵,但是当我这样做时,“a1”变成了一个零矩阵。但是,当我将输出分配给相同的“a”矩阵时,一切正常。谁能帮我?代码是在 Arduino IDE 上编写的。

double a[4][2], a1[4][2];
double T0E[4][4]={
  {0.1632, -0.3420, 0.9254, 297.9772},
  {0.0594, 0.9397, 0.3368, 108.4548},
  {-0.9848, 0, 0.1736, -280.5472},
  {0, 0, 0, 1}
};

const int axis_limits[4][2]=
  {
    { -160, 160 },
    { -135, 60 },
    { -135, 135 },
    { -90, 90 }
  };
  const unsigned int basex = 50, basez = 100, link1 = 200, link2 = 200, link3=30, endeff=link3+50;

double *inversekinematic(double target[4][4])
{

  // angle 1
  a[0][0] = -asin(target[0][1]);
  a[0][1] = a[0][0];
  if (a[0][0]<axis_limits[0][0] || a[0][0]>axis_limits[0][1] || isnan(a[0][0]))
  {
  bool error=true;
  }

  // angle 2
  double A = sqrt(pow(target[0][3]-cos(a[0][0])*endeff*target[2][2], 2) + pow(target[1][3]-sin(a[0][0])*endeff*target[2][2], 2));
  double N = (A - basex) / link1;
  double M = -(target[2][3]-endeff*target[2][0] - basez) / link2;
  double theta = acos(N / sqrt(pow(N, 2) + pow(M, 2)));
  a[1][0] = theta + acos(sqrt(pow(N, 2) + pow(M, 2)) / 2);
  a[1][1] = theta - acos(sqrt(pow(N, 2) + pow(M, 2)) / 2);

  // angle 3
  for (int i = 0; i <= 1; i++) 
  {
  a[2][i] = {asin(-(target[2][3]-endeff*target[2][0]-basez)/link2-sin(a[1][i]))-a[1][i]};
    }

  // angle 4
  for(int i = 0; i <=1; i++)
    {
      a[3][i] = {-asin(target[2][0])-a[1][i]-a[2][i]};
      }
      return &a[4][2];
}

void setup(){
  Serial.begin(9600);
}

void loop() {
  a1[4][2]={*inversekinematic(T0E)};
}

【问题讨论】:

  • 哦,我就放弃了。

标签: c++ function arduino return output


【解决方案1】:

当您键入 return &amp;a[4][2]; 时,您将返回第 5 行的第 3 个元素的地址。这是越界的,因为 C++ 使用从零开始的索引并且数组被声明为double a[4][2];。我想你要做的只是return a; 返回整个矩阵的地址。

另外,你做了很多奇怪的事情,比如用大小声明参数double target[4][4] 并使用初始化列表来分配单个元素,这对我来说看起来很不寻常。

我会尽量详细一点。在 C/C++ 中,数组只不过是指针。因此,当您将一个数组分配给另一个数组时,您实际上是在使它们指向内存中的相同数据。您需要做的是使用循环复制元素,或者使用memcpy(dest, src, size)。例如,如果要将double a[4][2] 的内容复制double b[4][2],则可以使用memcpy(b, a, sizeof(double) * 8); 之类的内容。如果您使用a = b;,那么ab 将指向内存中的相同位置。

【讨论】:

  • 这也会失败,因为他显然试图将一个数组分配给另一个数组。
  • 感谢您的回答。正如你所注意到的,我对此并不陌生。我无法返回;工作,它说'不能将'double(*)[2]'转换为'double'作为回报​​'。但是我将'a'矩阵作为全局传递并使用了 memcpy() 并且它工作得很好。当我没有用大小声明双目标时,我得到了错误。
【解决方案2】:

两点: 1.你的代码说函数inversekinematic()返回一个指向double的指针,而不是一个数组。 2. 你返回一个指向double 的指针,但它始终是同一个地址。

也许 typedef 将有助于简化代码?

typedef double Mat42[4][2];

Mat42 a, a1;

Mat42 *inversekinematic(double target[4][4])
{
        // ...
        return &a;
}

但是,对于您显示的代码,我不明白您为什么需要返回固定全局值的地址。也许你的真实代码可能会返回 'a' 或 'a1' 的地址,但如果它没有......

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-13
    • 2013-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多