I have a function which returns the address of a 4x2 matrix whose name is 'a'. This function computes the elements of 'a' matrix inside and returns the address of the matrix. When I use that function, I want to assign its output to a matrix called 'a1' but when I do so, 'a1' becomes a zero matrix. However, when I assign the output to the same 'a' matrix, everything works fine. Can anyone help me? The code is written on Arduino IDE.
我有一个函数返回名称为'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)};
}
2 个解决方案
#1
0
When you type return &a[4][2];
you are returning the address of the 3rd element of the 5th row. This is out of bounds, since C++ uses zero-based indexing and the array was declared as double a[4][2];
. I think what you want to do is just return a;
to return the address of the entire matrix.
当你输入return&a [4] [2]时;您将返回第5行第3个元素的地址。这是不受限制的,因为C ++使用从零开始的索引,并且数组被声明为double a [4] [2];。我想你想要做的只是回归;返回整个矩阵的地址。
Also, you're doing lots of strange things like declaring the parameter double target[4][4]
with a size and using initializer lists to assign single elements, which look unusual to me.
此外,你正在做很多奇怪的事情,比如用一个大小声明参数double target [4] [4]并使用初始化列表来分配单个元素,这看起来很不寻常。
I'll try to be a little more detailed. In C/C++, arrays are nothing more than pointers. So, when you assign one array to another array you are making them literally point to the same data in memory. What you will have to do is copy the elements with loops, or perhaps use memcpy(dest, src, size)
. For example, if you want to copy the contents of double a[4][2]
to double b[4][2]
, you would use something like memcpy(b, a, sizeof(double) * 8);
. If you use a = b;
then a
and b
are pointing to same locations in memory.
我会尝试更详细一些。在C / C ++中,数组只不过是指针。因此,当您将一个数组分配给另一个数组时,您使它们在字面上指向内存中的相同数据。你需要做的是用循环复制元素,或者使用memcpy(dest,src,size)。例如,如果要将double a [4] [2]的内容复制到double b [4] [2],则可以使用memcpy(b,a,sizeof(double)* 8);等内容。如果你使用a = b;然后a和b指向内存中的相同位置。
#2
0
Two points: 1. your code says the function inversekinematic()
returns a pointer to a double
, not an array. 2. you return a pointer to a double
, but it's always the same address.
两点:1。你的代码说函数inversekinematic()返回一个指向double的指针,而不是一个数组。 2.返回指向double的指针,但它始终是相同的地址。
Maybe typedefs will help simplify the code?
也许typedef有助于简化代码?
typedef double Mat42[4][2];
Mat42 a, a1;
Mat42 *inversekinematic(double target[4][4])
{
// ...
return &a;
}
But, for the code you've shown, I don't see why you need to return the address of a fixed global value. Perhaps your real code might return the address of 'a' or 'a1', but if it doesn't ...
但是,对于您显示的代码,我不明白为什么您需要返回固定全局值的地址。也许你的真实代码可能会返回“a”或“a1”的地址,但如果不是......
#1
0
When you type return &a[4][2];
you are returning the address of the 3rd element of the 5th row. This is out of bounds, since C++ uses zero-based indexing and the array was declared as double a[4][2];
. I think what you want to do is just return a;
to return the address of the entire matrix.
当你输入return&a [4] [2]时;您将返回第5行第3个元素的地址。这是不受限制的,因为C ++使用从零开始的索引,并且数组被声明为double a [4] [2];。我想你想要做的只是回归;返回整个矩阵的地址。
Also, you're doing lots of strange things like declaring the parameter double target[4][4]
with a size and using initializer lists to assign single elements, which look unusual to me.
此外,你正在做很多奇怪的事情,比如用一个大小声明参数double target [4] [4]并使用初始化列表来分配单个元素,这看起来很不寻常。
I'll try to be a little more detailed. In C/C++, arrays are nothing more than pointers. So, when you assign one array to another array you are making them literally point to the same data in memory. What you will have to do is copy the elements with loops, or perhaps use memcpy(dest, src, size)
. For example, if you want to copy the contents of double a[4][2]
to double b[4][2]
, you would use something like memcpy(b, a, sizeof(double) * 8);
. If you use a = b;
then a
and b
are pointing to same locations in memory.
我会尝试更详细一些。在C / C ++中,数组只不过是指针。因此,当您将一个数组分配给另一个数组时,您使它们在字面上指向内存中的相同数据。你需要做的是用循环复制元素,或者使用memcpy(dest,src,size)。例如,如果要将double a [4] [2]的内容复制到double b [4] [2],则可以使用memcpy(b,a,sizeof(double)* 8);等内容。如果你使用a = b;然后a和b指向内存中的相同位置。
#2
0
Two points: 1. your code says the function inversekinematic()
returns a pointer to a double
, not an array. 2. you return a pointer to a double
, but it's always the same address.
两点:1。你的代码说函数inversekinematic()返回一个指向double的指针,而不是一个数组。 2.返回指向double的指针,但它始终是相同的地址。
Maybe typedefs will help simplify the code?
也许typedef有助于简化代码?
typedef double Mat42[4][2];
Mat42 a, a1;
Mat42 *inversekinematic(double target[4][4])
{
// ...
return &a;
}
But, for the code you've shown, I don't see why you need to return the address of a fixed global value. Perhaps your real code might return the address of 'a' or 'a1', but if it doesn't ...
但是,对于您显示的代码,我不明白为什么您需要返回固定全局值的地址。也许你的真实代码可能会返回“a”或“a1”的地址,但如果不是......