Технический форум по робототехнике.
Scorpio » 09 июл 2018, 23:09
Конечно прямоугольная система координат. На кой нам коническая! Плюс векторное описание шрифта. Нормальные шрифты описываются с помощью кривых Безье. Но это уже следующий шаг...
Dmitry__ » 09 июл 2018, 23:19
Scorpio писал(а):Dmitry__ порой производит впечатление умного, образованного человека
Не понял сарказма

Я тупанул? Мог, можно подробнее?

Scorpio » 09 июл 2018, 23:46
Не заводись. Для меня ты незыблемый авторитет.
- Код: Выделить всё • Развернуть
#define L1 100 //длина первого плеча манипулятора в мм.
#define L2 100 //длина второго плеча манипулятора в мм.
#define Xmax 150
#define Ymax 150
//Функция выставляет servo1 servo2, на точку с координатами X,Y
void SetServosToPoint(float X, float Y)
{
if(abs(X)>Xmax || Y>Ymax || Y<0) return;
float L=sqrt(X*X+Y*Y);
float a1=acos(X/L);
float a2=acos((L*L+L1*L1-L2*L2)/2*L*L1);
float A=a1+a2;
float b1=PI/2-a1;
float b2=acos((L2*L2+L*L-L1*L1)/2*L2*L);
float B=PI/2-(b1+b2);
servo1.writeMicroseconds((int) map(A, 0, PI, 500, 2500));
servo2.writeMicroseconds((int) map(B, 0, PI, 500, 2500));
}
Будет работать вилимо только в левом квадранте, в правом наверное по другому надо считать. Не думал еще.
Dmitry__ » 10 июл 2018, 00:17
Scorpio писал(а):Не заводись. Для меня ты незыблемый авторитет.
Да я не завожусь, правда интересно. Тем более я легко мог ошибиться, т.к. на данный момент эту тему читаю по диагонали. Слишком это все сложно, и когда не занят этим в конкретный момент, можно лопухнуться очень легко.
Ну скажи, где ошибаюсь?
Scorpio писал(а):Будет работать вилимо только в левом квадранте, в правом наверное по другому надо считать.
Вот про это я и подумал первым делом. Должны быть искажения в виде удаления в горизонт в правом квадранте...
Сам код реально не смотрю, не из-за вредности
Добавлено спустя 7 минут 41 секунду:Блин, глянул код, думаю, что изменилось, почему код стал читаем? А потом посмотрел, автор изменился

dimamichev, стиль кода для подражания

Scorpio » 10 июл 2018, 00:20
Dmitry__ писал(а):Ну скажи, где ошибаюсь
Да не ошибаешься. Лень тебе просто вникать в полет моей мысли

В правом квадранте, манипулятор будет повернут зеркально и расчет слегка иизменится. Но принцип тот-же:
Получаем вектор, как часть буквы,
Разбиваем его на произвольное количество точек,
Вычисляем первую точку с учетом смещения каретки,
Ставим туда перо,
Вычисляем следующую точку,
Рисуем до нее линию (кривую,но очень коротенькую,
Вычисляем следующую.....
Scorpio » 10 июл 2018, 07:05
В правом квадранте все примерно также:
Перепишем немного скетч:
- Код: Выделить всё • Развернуть
#define L1 100 //длина первого плеча манипулятора в мм.
#define L2 100 //длина второго плеча манипулятора в мм.
#define Xmax 150
#define Ymax 150
//Функция выставляет servo1 servo2, на точку с координатами X,Y
//X<0 для левого квадранта, X>0 для правого
void SetServosToPoint(float X, float Y)
{
if(abs(X)>Xmax || Y>Ymax || Y<0 || X==0) return;
float L=sqrt(X*X+Y*Y);
float a1=acos(abs(X)/L);
float a2=acos((L*L+L1*L1-L2*L2)/2*L*L1);
float A=a1+a2;
if(X>0)A=PI-A;
float b1=PI/2-a1;
float b2=acos((L2*L2+L*L-L1*L1)/2*L2*L);
float B=PI/2-(b1+b2);
if(X>0)B+=PI/2;
servo1.writeMicroseconds((int) map(A, 0, PI, 500, 2500));
servo2.writeMicroseconds((int) map(B, 0, PI, 500, 2500));
}
Теперь должен работать в обоих случаях.
Наверное....
dimamichev » 10 июл 2018, 09:12
Попробовал функцию, в loop() прописал (прошу прощения за f_(1);f_(0); потом поправлю )
#define L1 65 //длина первого плеча манипулятора в мм.
#define L2 65 //длина второго плеча манипулятора в мм.
#define Xmax 100
#define Ymax 100
SetServosToPoint(-30,30);f_(1);f_(0);
SetServosToPoint(-35,35);f_(1);f_(0);
SetServosToPoint(-30,35);f_(1);f_(0);
SetServosToPoint(-35,30);f_(1);f_(0);
Фломастер улетел по стрелкам, сюда. Рабочий сектор гораздо меньше видимо теоретических возможностей.
Добавлено спустя 49 минут 55 секунд:
И ещё. Ограничения на значения углов поворота серв. У каждой версии манипулятора они свои. Даже если скопировать этот точь в точь, повторить исходную посадку коромысел вряд ли удастся.Поэтому граничные углы у каждого варианта свои. Ключевая рекомендация - центр рабочей зоны исполняющего уст-ва при значениях углов поворота серв в 90 градусов выполняется приблизительно.
- Вложения
-

-

Scorpio » 10 июл 2018, 18:30
Первый вариант функции не был рассчитан на отрицательные значения Х. Прежде чем управлять сервами, надо посмотреть что функция считает. Проверить правильно ли. Я не проверял. Надо дуинку прикупить )))
Добавлено спустя 41 минуту 34 секунды:При сборке манипулятора нужно сначала сервы выставить упр. Сигналом на 90 гр. А потом прикрутить штанги соотв. Иначе управлять расчетным методом будет сложно. Надо какие то смещения вводить.
Добавлено спустя 1 час 2 минуты 57 секунд:Попробуй так для начала:
- Код: Выделить всё • Развернуть
#define L1 100 //длина первого плеча манипулятора в мм.
#define L2 100 //длина второго плеча манипулятора в мм.
#define Xmax 150
#define Ymax 150
//Функция выставляет servo1 servo2, на точку с координатами X,Y
//X<0 для левого квадранта, X>0 для правого
void SetServosToPoint(float X, float Y)
{
if(abs(X)>Xmax || Y>Ymax || Y<0 || X==0) return;
float L=sqrt(X*X+Y*Y);
float a1=acos(abs(X)/L);
float a2=acos((L*L+L1*L1-L2*L2)/2*L*L1);
float A=a1+a2;
if(X>0)A=PI-A;
float b1=PI/2-a1;
float b2=acos((L2*L2+L*L-L1*L1)/2*L2*L);
float B=PI/2-(b1+b2);
if(X>0)B+=PI/2;
//servo1.writeMicroseconds((int) map(A, 0, PI, 500, 2500));
//servo2.writeMicroseconds((int) map(B, 0, PI, 500, 2500));
Serial.print("A= ");
Serial.println(map(A, 0, PI*2, 0, 360));
Serial.print("B= ");
Serial.println(map(B, 0, PI*2, 0, 360));
}
Если будет выдавать туфту, то надо найти ошибку. Вступаем в увлекательный период отладки/пуско-наладки!
Добавлено спустя 9 минут 33 секунды:Судя по фото, серва S1 повернута на 180°.В этом случае все углы для нее будут зеркальные, что надо учитывать в расчете.
dimamichev » 10 июл 2018, 18:48
Так что?,сервы отключить?, и в монитор порта смотреть, подставляя разные х и y?
С исходными углами мне кажется несложно, на картинке с точками я указывал границы углов. Просто А и В вычисляемые функцией при переходе к конкретным углам поворота будут иметь постоянные поправки, связанные с первоначальной посадкой коромысел. Их мне не трудно найти, нужно лишь указать точную привязку системы координат и углы отсчёта.
Scorpio » 10 июл 2018, 19:44
dimamichev писал(а):Так что?,сервы отключить?, и в монитор порта смотреть, подставляя разные х и y?.
Ага. Пока так, чтобы сервы не мучать.
Добавлено спустя 3 минуты 39 секунд:Если теоретически считает правильно (проверить транспортиром) то можно будет сервы подключать. Только зеркальность S1еще проверить
Dmitry__ » 10 июл 2018, 19:54
А чего бы не делать лог массива точек и заводить в эксель? Зачем бумагу переводить?
Да и нам будет интереснее
Добавлено спустя 3 минуты 29 секунд:Как мы в датчике касания, триангуляция:

dimamichev » 10 июл 2018, 20:09
- Код: Выделить всё • Развернуть
///////////// МАНИПУЛЯТОР ДЛЯ ГРАФИЧЕСКИХ ИЗОБРАЖЕНИЙ скетч СЕТКА КООРДИНАТНАЯ ДЕКАРТОВА ПРОТО //////////////////////////////
#include <Servo.h> // подключение библиотеки Servo
#define L1 65 //длина первого плеча манипулятора в мм.
#define L2 65 //длина второго плеча манипулятора в мм.
#define Xmax 100
#define Ymax 100
void setup()
{
Serial.begin(9600);
}
//////////////////////////////////////////////////////////////////////////////////////////////
void loop()
/////////////////////////////////////////////////////////////////////////
{
SetServosToPoint (-100,100);delay(10000);
}
//Функция выставляет servo1 servo2, на точку с координатами X,Y
//X<0 для левого квадранта, X>0 для правого
void SetServosToPoint(float X, float Y)
{
if(abs(X)>Xmax || Y>Ymax || Y<0 || X==0) return;
float L=sqrt(X*X+Y*Y);
float a1=acos(abs(X)/L);
float a2=acos((L*L+L1*L1-L2*L2)/2*L*L1);
float A=a1+a2;
if(X>0)A=PI-A;
float b1=PI/2-a1;
float b2=acos((L2*L2+L*L-L1*L1)/2*L2*L);
float B=PI/2-(b1+b2);
if(X>0)B+=PI/2;
//servo1.writeMicroseconds((int) map(A, 0, PI, 500, 2500));
//servo2.writeMicroseconds((int) map(B, 0, PI, 500, 2500));
Serial.print("A= ");
Serial.println(map(A, 0, PI*2, 0, 360));
Serial.print("B= ");
Serial.println(map(B, 0, PI*2, 0, 360));
}
Не успеваю за ходом мыслей (не своих). Сделал так.При любых координатах кроме 0,0 выдаёт А=0 В=0. Иначе ничего не выдаёт.
Добавлено спустя 5 минут 17 секунд:Ясно почему фломастер рванул именно туда - как раз 00
Добавлено спустя 4 минуты 8 секунд:А почему 0-360, а не 0-180?
Scorpio » 10 июл 2018, 20:12
Потому что 2пи.
Надо тогда по ходу расчета выводить. Подозреваю что acos не считает дуня
dimamichev » 10 июл 2018, 20:17
Scorpio писал(а):Потому что 2пи.
Надо тогда по ходу расчета выводить. Подозреваю что acos не считает дуня
Вообщем не пи... ясно. Не считает, но пишет красненьким, впрочем здесь нет acos:
http://arduino.ru/Reference
Scorpio » 10 июл 2018, 21:11
#include "math.h" попробуй