本帖最后由 黄钊 于 2017-10-29 04:35 编辑
产生个想法,干脆把这问题做成一个学习记录得了。
2017/10/29
范围失控问题解决了,
因为xy坐标数据类型是int, 在float l = abs(sqrt(x * x + y * y));里 xy类型不匹配,应该改成float l = abs(sqrt((float)x *(float) x +(float) y * (float)y));
2017/10/27
问题还是存在,当传来的坐标处于时空范围的时候l会大于lTotal
2017/10/18
到现在为止机械臂运行还算成功,能在一定范围内按照传来的坐标大概准确的运动。但是出现一个新问题,当只要当l大于180的时候,stepper1 和stepper2就会同时失控(顺时针不停的转动)
怀疑出现问题部分代码:
//这是传过来的坐标总尺寸的对角线长度,代表机械臂最大运动范围
float lTotal = abs(sqrt(320 * 320 + 240 * 240));
//这是坐标系原点到坐标的长度,代表机械臂实时运动范围
float l = abs(sqrt(x * x + y * y));
//lt1Pos 存储上一个循环的l值
double lt1Pos;
double lt2Pos;
//求转动的角度
double theta = atan2(y, x);
double thetaPos;
double thetaDiff = theta - thetaPos;
//l/lTotal是坐标到原点和对角线比值,用这个来mapping电机转动圈数。
double lt1 = (l / lTotal) * (-2000);
double lt2 = (l / lTotal) * (-1500);
//求出与当前循环lt1上一个循环的lt1插值
double lt1Diff = lt1 - lt1Pos;
double lt2Diff = lt2 - lt2Pos;
2017/10/18
问题突然解决了,翻阅atan2资料发现要用double类型,把所有long改成double就好了。这个么简单的问题花了好长时间啊。。。
2017/10/17
现在问题就是如图片所示,只有鼠标跨过这条黑线上的点,电机才会有正反运动,其他坐标都没有反应。
2017/10/15
现在用LED来显示传输到ARDUINO的xy坐标的位置(比如x > 200时,led点亮),得到结果是传输到arduino上x,y的数据是正确的。但是电机只会在某一个特定的xy坐标上(如x>or<92, y>or<135)做出正反运动的反应,而且运动幅度都是一样的.
代码:
void headToPoint(int x, int y) {
long theta = atan2(y, x);
long thetaPos;
long thetaDiff = theta - thetaPos;
// stepper3.move(thetaDiff * (180 / PI));
// delay(100);
if (stepper3.distanceToGo() == 0) {
stepper3.moveTo( thetaDiff * (180 / PI));
thetaPos = theta;
delay(100);
}
if (y < 200) {
digitalWrite(led, HIGH);
} else {
digitalWrite(led, LOW);
}
}
2017/10/14
我用一个LED来显示thetaDiff的正负变化,是有正负的。弧度值现在也转换为角度值了,开始出现反方向运动了。但是新问题是,总是按照一个幅度频率一致的往复运动。好像并没有受xy坐标的控制。现在最新的headToPoint 修改内容如下:
void headToPoint(int x, int y) {
long theta = atan2(y, x);
long thetaPos;
long thetaDiff = theta - thetaPos;
// if (thetaDiff > 0) {
// digitalWrite(led, HIGH);
// } else {
// digitalWrite(led, LOW);
// }
if (stepper3.distanceToGo() == 0) {
stepper3.moveTo( thetaDiff * (180 / PI));
thetaPos = theta;
delay(100);
}
==========================================================================================
之前 最帅的老饼 指出我的问题太笼统,实在是因为当时不知道问题在哪。现在找到了,但解决不了,如果10位大神之一哪位有时间望帮我解答一下。
下面是修改过的问题和代码:
==========================================================================================
现在我在做一个用摄像头跟踪一个移动的黑点,然后想用一个带有三个步进电机的机械臂实时的把黑点的运动路径画在纸上。连抄带改,在Processing 端已经能跟踪黑点,并把byte信号传给arduino。我找到了accelStepper库,发现可以用在这个程序里。目前我只想先让控制机械臂顺时针逆时针转动的stepper3电机能够根据传来的坐标转动。这段代码里,x,y坐标已经成功传到ARDUINO里,而且电机也动了。但是不知道为什么一直按照一个频率往一个方向转动。三角函数算法这我检查很多遍,好像没有问题。xy坐标也在不断更新,很奇怪。在此献上一首陈小春的 神啊,救救我吧!
设备:a4988, 山寨dobot
arduino代码:
#include <AccelStepper.h>
//#include <MultiStepper.h>
const byte MOVETO = 0;
const byte LINETO = 1;
const byte ORIGIN = 2;
const float MOTOR_DIFF = 1.3;
const int MICROSTEPS = 16;
#define STEPPERX_DIR_PIN 5
#define STEPPERX_STEP_PIN 2
#define STEPPERY_DIR_PIN 6
#define STEPPERY_STEP_PIN 3
#define STEPPERZ_DIR_PIN 7
#define STEPPERZ_STEP_PIN 4
#define en 8
AccelStepper stepper1(AccelStepper:RIVER, STEPPERX_STEP_PIN, STEPPERX_DIR_PIN);
AccelStepper stepper2(AccelStepper:RIVER, STEPPERY_STEP_PIN, STEPPERY_DIR_PIN);
AccelStepper stepper3(AccelStepper:RIVER, STEPPERZ_STEP_PIN, STEPPERZ_DIR_PIN);
int xPos = 0;
int yPos = 0;
void setup() {
Serial.begin(9600);
stepper1.setMaxSpeed(200.0);
stepper1.setAcceleration(100.0);
// stepper1.moveTo(100000);
stepper2.setMaxSpeed(300.0);
stepper2.setAcceleration(100.0);
// stepper2.moveTo(1000000);
stepper3.setMaxSpeed(300.0);
stepper3.setAcceleration(100.0);
// stepper3.moveTo(-1000000);
pinMode(en, OUTPUT);
digitalWrite(en, LOW);
}
void loop( ) {
//receiving data (bytearrays) from Serial,
if (Serial.available() >= 1) {
byte type = Serial.read();
byte xByte = Serial.read();
byte xByte2 = Serial.read();
byte xByte3 = Serial.read();
byte xByte4 = Serial.read();
byte yByte = Serial.read();
byte yByte2 = Serial.read();
byte yByte3 = Serial.read();
byte yByte4 = Serial.read();
//adding bytes for x and y parameter
long x = (long) xByte + (long) xByte2 + (long) xByte3 + (long) xByte4;
long y = (long) yByte + (long) yByte2 + (long) yByte3 + (long) yByte4;
//compensating the different motors and gearwheels
y *= MOTOR_DIFF;
//motor driver requires 16 microsteps per full stepp
y *= MICROSTEPS;
x *= MICROSTEPS;
headToPoint(x, y);
stepper3.run();
}
//将xy坐标点转换成电机的转动
void headToPoint(long x, long y) {
//三角函数算出角度
long theta = atan2(y, x);
long thetaPos;
//角度变化
long thetaDiff = theta - thetaPos;
if (stepper3.distanceToGo()==0) {
stepper3.move( thetaDiff*10);
}
thetaPos = theta;
delay(10);
}
|