main.cpp
#include "class_dec.h"
#include "auxiliary.h"
myRobot robot;
int main()
{
while(1)
{
robot.Operation();
}
}
class_def.cpp
/*************************************************************************************************/
/*@note
這個文件里定義了所有的類的成員函數
*/
/**includes***************************************************************************************/
#include "auxiliary.h"
#include "class_dec.h"
/**CS::Fuctions***********************************************************************************/
/*@note
CS的構造函數
*/
CS::CS()
{
strcpy(name,"TCS");
x=0;
y=0;
angle=0;
//mov(3,3);
}
/*@note
用來設定新建坐標系相對於世界坐標系的平移、旋轉量
*/
void CS::Set(char n[11],float a,float b,float c)
{
strcpy(name,n);
x=a;
y=b;
angle=c;
/*mov(0,0)=cos(angle);
mov(0,1)=sin(angle);
mov(0,2)=x;
mov(1,0)=-sin(angle);
mov(1,1)=cos(angle);
mov(1,2)=y;
mov(2,0)=0;
mov(2,1)=0;
mov(2,2)=1;*/
}
/*@note
獲取坐標系名稱
*/
char* CS::GetName()
{
return name;
}
/*@note
插入該坐標系下用戶要求機器人到達的坐標
*/
void CS::Insert(float a,float b)
{
para1=a;
para2=b;
}
/*@note
將該坐標系下的坐標變換至世界坐標系并更新關節坐標系中的坐標值
*/
void CS::Transform()
{
MatrixXd mov(3,3);
mov(0,0)=cos(angle);
mov(0,1)=sin(angle);
mov(0,2)=x;
mov(1,0)=-sin(angle);
mov(1,1)=cos(angle);
mov(1,2)=y;
mov(2,0)=0;
mov(2,1)=0;
mov(2,2)=1;
MatrixXd coor_TCS(3,1);
coor_TCS(0,0)=para1;
coor_TCS(1,0)=para2;
coor_TCS(2,0)=1;
MatrixXd coor_WCS(3,1);
coor_WCS=mov*coor_TCS;
if((coor_WCS(0,0)*coor_WCS(0,0)+coor_WCS(1,0)*coor_WCS(1,0))>=400) //這裡假定機器人兩個手臂的長度都是10,所以半徑20的圓以外的地方是到不了的
{
cout<<"Robot can't reach that point!"<<endl;
}
else
{
cout<<"The coordinates of the Robot in WCS are shown as below:"<<endl<<"("<<coor_WCS(0,0)<<","<<coor_WCS(1,0)<<")"<<endl;
robot.Set(acos(sqrt(coor_WCS(0,0)*coor_WCS(0,0)+coor_WCS(1,0)*coor_WCS(1,0))/20)+atan(coor_WCS(1,0)/coor_WCS(0,0)),\
2*(90-acos(sqrt(coor_WCS(0,0)*coor_WCS(0,0)+coor_WCS(1,0)*coor_WCS(1,0))/20)));
}
}
/**myRobot::Functions*****************************************************************************/
/*@note
構造函數
*/
myRobot::myRobot()
{
angle1=90;
angle2=180;
CS* p;
p=new CS;
char str[3]={'W','C','S'};
p->Set(str,0,0,0);
cs_vector.push_back(*p);
}
/*@note
更新關節坐標系下的坐標值
*/
void myRobot::Set(float a,float b)
{
angle1=a;
angle2=b;
}
/*@note
判斷用戶是新建坐標系還是移動機器人
*/
void myRobot::Operation()
{
input=Input();
if(strcmp(input.OperationType,"S")==0)
{
CS* p;
p=new CS;
p->Set(input.CSName,input.para1,input.para2,input.para3);
cs_vector.push_back(*p);
}
else
{
PTPMove();
}
}
/*@note
實現坐標變換并更新關節坐標系下坐標
*/
void myRobot::PTPMove()
{
for(it=cs_vector.begin();it!=cs_vector.end();it++)
{
if(strcmp(it->GetName(),input.CSName)==0)
{
it->Insert(input.para1,input.para2);
it->Transform();
Show();
break;
}
}
}
/*@note
顯示關節坐標系下坐標
*/
void myRobot::Show()
{
cout<<"The coordinates of the Robot in Joint_CS are shown as below:"<<endl<<"("<<angle1<<","<<angle2<<")"<<endl;
}
class_dec.h
#ifndef __CLASS_DEC_H
#define __CLASS_DEC_H
#include <iostream>
#include <vector>
#include <Eigen/Dense>
#include <math.h>
using namespace std;
using Eigen::MatrixXd;
class CS
{
public:
CS();
void Set(char n[11],float a,float b,float c);
char* GetName();
void Insert(float a,float b);
void Transform();
protected:
char name[11];
float x;
float y;
float angle;
//MatrixXd mov;
float para1;
float para2;
};
class myRobot
{
public:
myRobot();
void Set(float a,float b);
void Operation();
void PTPMove();
void Show();
protected:
float angle1;
float angle2;
vector<CS> cs_vector;
vector<CS>::iterator it;
};
extern myRobot robot;
#endif
auxiliary.cpp
#include "auxiliary.h"
InputCom input;
InputCom Input()
{
char str[11];
InputCom input;
cout<<"Input OperationType 'S'or'M':"<<endl;
cin>>str;
strcpy(input.OperationType,str);
cout<<"Input CSName:"<<endl;
cin>>str;
strcpy(input.CSName,str);
cout<<"Input para1:"<<endl;
cin>>str;
input.para1=Extraction(str);
cout<<"Input para2:"<<endl;
cin>>str;
input.para2=Extraction(str);
if(strcmp(input.OperationType,"S")==0)
{
cout<<"Input para3:"<<endl;
cin>>str;
input.para3=Extraction(str);
return input;
}
else
{
input.para3=0;
return input;
}
}
float Extraction(char str[11])
{
int i,k;
float a=0;
for(i=0;str[i]!='\0';i++)
{
if(str[i]=='.')
{
k=i;
}
}
if(str[0]=='-')
{
for(i=0;i<k-1;i++)
{
a+=((float)str[k-i-1]-48)*Index1(i);
}
for(i=1;str[k+i]!='\0';i++)
{
a+=((float)str[k+i]-48)*Index2(i);
}
}
else
{
for(i=0;i<k;i++)
{
a+=((float)str[k-i-1]-48)*Index1(i);
}
for(i=1;str[k+i]!='\0';i++)
{
a+=((float)str[k+i]-48)*Index2(i);
}
}
return a;
}
float Index1(int n)
{
float a=1,i;
for(i=n;i!=0;i--)
{
a*=10;
}
return a;
}
float Index2(int n)
{
float a=1,i;
for(i=n;i!=0;i--)
{
a*=0.1;
}
return a;
}
auxiliary.h
#ifndef __AUXILIARY_H
#define __AUXILIARY_H
#include <iostream>
#include <string.h>
using namespace std;
/*@note
用於存儲用戶輸入的內容
*/
typedef struct
{
char OperationType[11];
char CSName[11];
float para1;
float para2;
float para3;
}InputCom;
extern InputCom input;
InputCom Input();
float Extraction(char str[40]);
float Index1(int n);
float Index2(int n);
#endif
我認真檢查過代碼,好像沒什麼問題。編譯也能順利通過(0錯誤,0警告)。
然而,當我嘗試新建坐標系時會無法執行主函數的大循環。或者,當我嘗試移動機器人時,重新輸出的坐標是有問題的。而且,這兩種情況下都會觸發Windows關閉程序并報錯。
我懷疑是哪裡的內存溢出了。
已經咨詢過陳旭展助教,然而並沒有得到解決。希望陳冰老師出差回來後能看一下我的這個問題。或者其他兩位助教能幫助我解決它。
如果有看到這篇隨筆并有一些想法的同學,請移步“文件”下載我的這份代碼。不勝感激!
我把bug解決了!!!!!!
問題出在Extraction裡面,我在這個函數內部試圖每次都指出小數點的位置,這導致用戶在輸入的不是顯
式(即寫出小數點)的浮點數的時候會使尋找小數點的指針指向字符數組外面!!!!
這被稱為“執行了無效的內存引用”,所以每次程序都會被Windows系統強制關閉!!!!
而我是在嘗試debug的時候發現這個報錯的。
所以我稍微修改了Input函數的位置,使它脫離類的控制(控制台脫離類);并將它改為返回void類型(因
為有全局變量可以直接用)。最重要的是輸入數據時要顯式地寫成浮點數即可。此外還修正了角度和弧度
的一些錯誤。
昨天忘記把截圖發上來了,現在補上。
第一張是新建(用S來指示)了兩個(也可以更多,只與內存容量有關)名為TCS1和TCS2的任務坐標系,para1~3分別是坐標系相對於世界坐標系WCS的原點坐標和旋轉角:
第二張是分別移動(用M來指示)機器人至各自坐標系中的(1.0,1.0)處,并給出了相應的世界坐標系和關節坐標系下的坐標:
第三張是移動機器人至世界坐標系(初始化時自動定義的)中的(10.0,0.0)處,形成一個等邊三角形(我設定兩個機械臂長度都是10):