roboforum.ru

Технический форум по робототехнике.

Вопросы новичка.

Как собрать и запрограммировать робота на Arduino(Freeduino, Roboduino, Seeduino ...). Используем Wiring и Processing.

Re: Вопросы новичка.

Сообщение Scorpio » 16 июл 2018, 08:07

dimamichev писал(а):me:goto me;
:good:
Закоменть parking после рисования вектора и не будет возвращаться (последняя строчка кода)
Аватара пользователя
Scorpio
 
Сообщения: 2681
Зарегистрирован: 30 сен 2008, 18:49
Откуда: Где-то в Латинской Америке

Re: Вопросы новичка.

Сообщение dimamichev » 16 июл 2018, 10:10

За goto простите, про parking не понял, в том скетче где его написал всё так как надо.
Спасибо буду пробовать писать в прямоугольной системе координат.
Попутно хочется попробовать писать в воздухе светом - флизлайт рисунок, как на текущей моей аватарке.

Добавлено спустя 5 минут 44 секунды:
:D
Код: Выделить всёРазвернуть
:D meeee...: goto meeee....;


Добавлено спустя 4 минуты 53 секунды:
Вроде дошло...про паркинг.

Добавлено спустя 1 час 39 минут 4 секунды:
Код: Выделить всёРазвернуть
#include <Servo.h> 

Servo servo1;//указываем сервопривод основного поворота (при увел. угла - поворот рычага ВЛЕВО)
Servo servo2;//указываем сервопривод дополнительного поворота (при увел. угла - поворот рычага ВПРАВО)
Servo servo3;//указываем сервопривод подъёмника (при увел. угла - поворот рычага ВВЕРХ)

byte n=30;// единица временного интервала

#define S1_0 110 //начальный угол 1 сервопривода
#define S2_0 114 //начальный угол 2 сервопривода
#define S3_UP 110 //начальный угол 3 сервопривода (угол подъёма фломастера над листом)
#define S3_DW 85  //угол 3 сервопривода (угол опускания фломастера на лист)


String inputString = "";

//текущее положение пера
int CurX=1000;
int CurY=1000;
// Текущее состояние пера опущено/поднято
boolean PenIsDown=false;
//параметры манипулятора
#define L1 65  //длина первого плеча манипулятора в мм.
#define L2 65  //длина второго плеча манипулятора в мм.
#define Xmax 120//значение граничных координат
#define Ymax 115//значение граничных координат
#define Acor1 352//поправка на посадку качалки сервы 1
#define Acor2 220//поправка на посадку качалки сервы 2
#define Ymin 50//значение граничных координат
// ограничение длины вектора в мм
#define Dmax 50
// разбивать линию на точки через каждые Dstep в мм
#define Dstep 3

//Для аварийной остановки в процессе рисования
boolean StopFlag=false;
//Для работы с эмулятором заменить на true
boolean EmulatorFlag=false;
//boolean EmulatorFlag=true;

void setup() {
Serial.begin(19200);
if(!EmulatorFlag)
   {
     servo1.attach(5);// подключаем переменную servo к соответствующему выводу платы Ардуино
     servo2.attach(6);
     servo3.attach(7);
   }
Parking();
Serial.println("RBT");
delay(1000);
}
//////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
void loop() {
//CheckSerial();
  Parking();
  for (int sc=6;sc>0;sc--)
  {
  SetServosToPoint(55-17*sc,100);
 
  ////// буква Р ////////
  DrawVector(22,100);DrawVector(8,180);DrawVector(9,1280);DrawVector(8,0);
  up_down_pen(false);
  ////////////////////////////////////////////////////
  delay(100);
  }
  me:goto me;
}
//////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
//выдержка времени, возвращающая true, если пришел символ в COM (ПОКА НЕ ЗАДЕЙСТВОВАНА)
//boolean DelayWithStop(int ms)
//{
//  while (!Serial.available())
//  {
//    delay(5);
//    ms-=5;
//    if(ms<0)break;
//  }
//  StopFlag=Serial.available();
//  return Stopflag;
//}

///////////////////////////////////////////////////////////////////////////
// устанавливает механизм в начальное положение
void Parking()
{
servo3.write(S3_UP);
delay(1000);
servo1.write(S1_0);//начальная установка положения
servo2.write(S2_0);
CurX=1000;CurY=1000;//Начальная точка для рисования не определена.
}
/////////////////////////////////////////////////////////////////////////
void  up_down_pen(boolean  down)
{
  if(PenIsDown^down)
  {
    byte a3;
    if(down)
      {
        if(!EmulatorFlag)
        {
          a3=S3_UP;
          while (a3>S3_DW){servo3.write(a3--);delay(n);}
        }
        else Serial.println("DWN");
      }
      else 
      {
        if(!EmulatorFlag)
        {
          a3=S3_DW;
          while (a3<S3_UP){servo3.write(a3++);delay(n);}
        }
        else Serial.println("UP"); 
      }
    PenIsDown=down;
  }
   Serial.print("Pen is ");
   Serial.println(PenIsDown);
}
////////////////////////////////////////////////////////////////////////////////
//Рисует отрезок длины d в направлении a(в градусах)
//либо описывает правильную дугу, с диаметром d в направлении a(значения угла задаются как 1000+а)
//либо переставляет перо на конец вектора, при отрицательных d
void DrawVector(int d, float a)
{
  bool IsArc = false;
  if (a > 999) {
    IsArc = true;  //Чтобы обозначить рисование дуги, к значению угла добавляется 1000
    a -= 1000;
  }
  if (d > Dmax || a < 0 || a > 359)return; // не корректные параметры
  if (CurX == 1000 || CurY == 1000)return; // не задана начальная точка
  if (d < 0) //задана перестановка пера
  {
    up_down_pen(false);//поднимем перо
    d = abs(d);
    GoToFinLine(d, a);
  } else //задано рисование
  {
    up_down_pen(true);//опустим перо
    if (!IsArc) //рисование отрезка
    {
      int n = d / Dstep; //разобьем линию на n отрезков.
      for (int i = 1; i <= n; i++)GoToFinLine(Dstep, a);//нарисуем отрезки по очереди
      d -= n * Dstep;
      if (d > 0)GoToFinLine(d, a); //последнюю точку нарисуем отдельно для точности.
    }
    else //рисование дуги
    {
      //посчитаем координаты центра окружности
      float x1, y1;
      float x0 = CurX + d / 2 * cos(GradToRad(a));
      float y0 = CurY + d / 2 * sin(GradToRad(a));
      int nn = d * PI/2 / Dstep; //разобьем дугу на n отрезков.
      float da = PI / nn;// вычислим угловой шаг
      float aa = GradToRad(a);
     
      for (int i = 1; i <= nn; i++)
      {
        //будем вычислять координаты точек, принадлежащих дуге
        aa += da;
        if(aa>PI*2)aa-=PI*2;
        //Будем считать из центра окружности в обратном направлении заданному
        x1 = x0 - d / 2 * cos(aa);
        y1 = y0 - d / 2 * sin(aa);
        //и рисовать линию апроксимации
        SetServosToPoint(x1, y1);
        delay(n*3);
      }
    }

  }
}
///////////////////////////////////////////////////////////////////////////////
// функция перемещает перо в конец заданного вектора
void GoToFinLine(int d,float a)
{
  if(StopFlag)return;
  //определим координаты конца вектора
    int x=CurX+d*cos(GradToRad(a));
    int y=CurY+d*sin(GradToRad(a));
   //переместим перо
    SetServosToPoint(x,y);
    delay(n*d);// выдержка времени для отработки механизма, зависящая от длины пути.
}
//////////////////////////////////////////////////////////////////////////////////
//Функция выставляет servo1 servo2, на точку с координатами X,Y
//X<0 для левого квадранта, X>0 для правого
void SetServosToPoint(int X, int Y)
{
  if(abs(X)>Xmax || Y>Ymax || Y<Ymin) return;
  CurX=X;CurY=Y;
// X=-X;
  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;
  A=PI-A;// вариант, если серва1 повернута на 180°
  float b1=PI/2-a1;
  float B=acos((L2 * L2 + L1 * L1 - L * L) / (2 * L2 * L1));
//  Serial.print("A= ");
//  Serial.println(180*A/PI);
//  Serial.print("B= ");
//  Serial.println(180*B/PI);
  if(!EmulatorFlag)
    {
      servo1.writeMicroseconds(RadianToMcs(A)+Acor1);
      servo2.writeMicroseconds(RadianToMcs(B)+Acor2);
    }
    else
    {
      Serial.print(RadianToMcs(A));   
      Serial.print("&");   
      Serial.println(RadianToMcs(B));     
    }

//  Serial.print("servo1= ");
//  Serial.println(RadianToMcs(A));
//  Serial.print("servo2= ");
//  Serial.println(RadianToMcs(B));
//  Serial.print("Current point: X= ");
//  Serial.print(X);
//  Serial.print(" Y= ");
//  Serial.println(Y);
}
/////////////////////////////////////////////////////////////////////
int RadianToMcs(float rad)
{
  int grad=180*rad/PI;
  return map(grad, 0, 180, 500, 2500);
}
/////////////////////////////////////////////////////////////////////
float GradToRad(float grad)
{
  float rad=PI*grad/180;
  return rad; 
}
////////////////////////////////////////////////////////////////////////////////////////////
//Задавать строку координат в виде X,Y (Например: -40,60)
// Либо вектор в виде d:a, где d - длина вектора в мм (отрицательное значение состветствует проходу с поднятым пером),
// a - угол направления рисования в диапазоне 0...360°

void CheckSerial()
{

  while (Serial.available())
  {
    char inChar = (char)Serial.read();
  if (inChar == '\n')
  {
   MakeCmd();
   inputString="";
   break;
  }
  else inputString += inChar;
  }
}
/////////////////////////////////////////////////////////////////////////////////////////////////
void MakeCmd()
{
  if(inputString.length()<3)return;
  if(inputString.startsWith("RBT?")){Serial.println("RBT");return;}//подключение к эмулятору
  int k=inputString.indexOf(',');
  if(k>0)//получены координаты точки
  {
    int x=inputString.substring(0,k).toInt();
    int y=inputString.substring(++k).toInt();
    x=constrain(x, -Xmax, Xmax);
    y=constrain(y, Ymin, Ymax);
    Serial.println("Set point:");
    Serial.print("X= ");
    Serial.print(x);
    Serial.print(" Y= ");
    Serial.println(y);
    SetServosToPoint(-x,y);
  }else
  {
    k=inputString.indexOf(':');
    if(k<0){Serial.println("!!!");return;} //не правильная команда
    //получены параметры вектора
    int d=inputString.substring(0,k).toInt();
    d=constrain(d, -Dmax, Dmax);
    float a=inputString.substring(++k).toFloat();
   // a=constrain(a, 0, 360);
    Serial.println("Draw vector:");
    Serial.print("d= ");
    Serial.print(d);
    Serial.print(" a= ");
    Serial.println(a);
    DrawVector(d,a);
    up_down_pen(false);//поднимем перо
    if(!EmulatorFlag){}
    //Parking();//пока убираем, чтобы посмотреть результаты
  }

}
//////////////////////////////////////////////////////////////////////////////////////


Это хитрость ?!, справа печатные, слева прописные.
Вложения
20180716_084520.jpg
Аватара пользователя
dimamichev
 
Сообщения: 1386
Зарегистрирован: 03 янв 2013, 16:27

Re: Вопросы новичка.

Сообщение Scorpio » 16 июл 2018, 15:44

Да, почерк у нас не очень пока...
Аватара пользователя
Scorpio
 
Сообщения: 2681
Зарегистрирован: 30 сен 2008, 18:49
Откуда: Где-то в Латинской Америке

Re: Вопросы новичка.

Сообщение Scorpio » 17 июл 2018, 04:09

Закрепим полученные знания в картинках:
formulasU.jpg
Аватара пользователя
Scorpio
 
Сообщения: 2681
Зарегистрирован: 30 сен 2008, 18:49
Откуда: Где-то в Латинской Америке

Re: Вопросы новичка.

Сообщение dimamichev » 17 июл 2018, 09:46

По 3 картинке не ясно со знаками. Хс,Ус ниже Х0,У0, а получает "+". Х1,У1 выше, а получает "-".

Добавлено спустя 1 час 48 минут 50 секунд:
Чуть увеличил количество рисуемых символов в старом варианте. Может и в новом пойти по сегментному принципу, если не во всех символах на индикатор, то в нескольких на один. Только подумать над "траекторией прохождения". Индикатор-матрица, наверное более устойчива к искажениям в зависимости от местоположения на поле?
Вложения
20180717_083018.jpg
Аватара пользователя
dimamichev
 
Сообщения: 1386
Зарегистрирован: 03 янв 2013, 16:27

Re: Вопросы новичка.

Сообщение Scorpio » 17 июл 2018, 15:50

Все в твоих руках. Я уже удовлетворился этой темой. Интересно было научится писать расчетным методом при такой конструкции манипулятора.
На картинке общая теория подсчетов. В скетче более подробно, с учетом зон.
Аватара пользователя
Scorpio
 
Сообщения: 2681
Зарегистрирован: 30 сен 2008, 18:49
Откуда: Где-то в Латинской Америке

Re: Вопросы новичка.

Сообщение dimamichev » 17 июл 2018, 16:12

Понял, буду сам дальше, если не заленюсь.Функции, надеюсь пригодятся.

Добавлено спустя 5 минут 54 секунды:
Спасибо.
Аватара пользователя
dimamichev
 
Сообщения: 1386
Зарегистрирован: 03 янв 2013, 16:27

Re: Вопросы новичка.

Сообщение Scorpio » 17 июл 2018, 17:03

Не зацикливайся сильно на буковках. Надо совершенствоваться.
Если научишь свою конструкцию переставлять шашки на доске - подарю тебе свою программку управления шашечным роботом :wink:
Аватара пользователя
Scorpio
 
Сообщения: 2681
Зарегистрирован: 30 сен 2008, 18:49
Откуда: Где-то в Латинской Америке

Re: Вопросы новичка.

Сообщение dimamichev » 17 июл 2018, 17:33

На буковках тоже интересно. Надо подумать над описанием построений в полярной системе координат.
А с шашками... неожиданно. Но если ставить цель использовать именно этот вариант манипулятора (проще не бывает), то как мне видится это миниатюрный электромагнит, шайбы стальные крашеные - шашки и мини доска 7см на 7см.
Аватара пользователя
dimamichev
 
Сообщения: 1386
Зарегистрирован: 03 янв 2013, 16:27

Re: Вопросы новичка.

Сообщение Scorpio » 17 июл 2018, 17:44

Вполне себе разумно. Правда у меня доска сенсорная, чтобы можно было определять ход человека. Но для начала можно и так. Либо поставить сверху камеру, для считывания расстановки6 доски.

Добавлено спустя 9 минут 16 секунд:
Вообще пусть сам с собой играет. Доска слишком маленькая, чтобы играть с человеком.
Аватара пользователя
Scorpio
 
Сообщения: 2681
Зарегистрирован: 30 сен 2008, 18:49
Откуда: Где-то в Латинской Америке

Re: Вопросы новичка.

Сообщение dimamichev » 17 июл 2018, 18:45

Scorpio писал(а):Добавлено спустя 9 минут 16 секунд:
Вообще пусть сам с собой играет. Доска слишком маленькая, чтобы играть с человеком.

Вот именно. За человека шашки может двигать манипулятор. "За", а не "вместо". Вопрос как "сообщить" ему о воле играющего с меньшими трудозатратами.

Добавлено спустя 21 минуту 19 секунд:
По картинке: Математика на ней важная, но нет привязки по направлениям координатных осей. Сейчас только допирает где начало отсчёта, куда оси направлены.
Аватара пользователя
dimamichev
 
Сообщения: 1386
Зарегистрирован: 03 янв 2013, 16:27

Re: Вопросы новичка.

Сообщение Scorpio » 18 июл 2018, 03:55

dimamichev писал(а):как "сообщить" ему о воле играющего с меньшими трудозатратами.

Проще всего общаться с роботом голосом. Если у вас в семье имеется хоть один смартфон на андроиде, то можем совместно (я буду только подсказывать) реализовать голосовое управление. А заодно, нарисуем роботу мордочку с выражением эмоций, а телефон закрепишь рядом с манипулятором. К дуине придется подключить дешевый ВТ модуль.
dimamichev писал(а):но нет привязки по направлениям координатных осей.

Вот тебе редактируемый файл - улучшай как считаешь нужным:
Теория расчетов.zip
(18.88 КиБ) Скачиваний: 0
Аватара пользователя
Scorpio
 
Сообщения: 2681
Зарегистрирован: 30 сен 2008, 18:49
Откуда: Где-то в Латинской Америке

Re: Вопросы новичка.

Сообщение dimamichev » 18 июл 2018, 09:55

Тогда может попробуем попроще, для начала - смартфон с мордочкой, ардуино с блютуз модулем, манипулятор с фломастером и ... крестики-нолики?
Квадроподом я уже управлял (ранее здесь писал), используя планшет и блютуз модуль, а так же приложение RemoteXY.
Аватара пользователя
dimamichev
 
Сообщения: 1386
Зарегистрирован: 03 янв 2013, 16:27

Re: Вопросы новичка.

Сообщение dimamichev » 18 июл 2018, 14:49

Код: Выделить всёРазвернуть
/////////////////////////////////////////////////////////////////////////
//Функция выставляет servo1 servo2, на точку с полярными координатами L,Q
//L расстоямие в мм от полюса,Q угол от полярной оси в градусах
void SetServosToPoint(float L, float Q)
{

  if(L>=Lmax ||L<=Lmin  ||Q>= Qmax ) return;
  float lp=65; //длина одного из равных плеч
  float B=acos(1.00-(L*L)/(2*lp*lp));
  float A=(PI*Q/180)+(B/2)-(PI/2);
  Serial.print("A= ");
  Serial.println(180*A/PI);
  Serial.print("B= ");
  Serial.println(180*B/PI);
  servo1.writeMicroseconds(RadianToMcs(A)+Acor1);
  servo2.writeMicroseconds(RadianToMcs(B)+Acor2);
  delay(5*n);
  int CurL=L;int CurQ=Q;

  Serial.print("Current point: L= ");
  Serial.print(L);
  Serial.print(", Q= ");
  Serial.println(Q);
}
//////////////////////////////////////////////////////////////////////
//функция перевода радиан в микросекунды для управления сервоприводами
int RadianToMcs(float rad)
{
  int grad=180*rad/PI;
  grad=map(grad, 0, 180, 500, 2500);
  return grad;
}
//////////////////////////////////////////////////////////////////////

Сделал аналог функции выставления точки в полярных координатах. Так как надо - одна координата линейная, другая угловая.
Аватара пользователя
dimamichev
 
Сообщения: 1386
Зарегистрирован: 03 янв 2013, 16:27

Re: Вопросы новичка.

Сообщение Scorpio » 18 июл 2018, 16:33

dimamichev писал(а):Тогда может попробуем попроще

качай MIT AI2 Companion на телефон, делай гугловский акаунт (если нет еще), иди на ai2.appinventor.mit.edu (с компа)и начинай творить распознавалку. Будут вопросы - задавай. Там все проще паренной репы, а результат быстрый и надежный.
Параллельно ищи электромагнитик для шашек. Моя прога управления позволяет двигать шашки на экране компа, а твой робот будет их переставлять. В общем горизонты для творчества у тебя безграничные.
Аватара пользователя
Scorpio
 
Сообщения: 2681
Зарегистрирован: 30 сен 2008, 18:49
Откуда: Где-то в Латинской Америке

Пред.След.

Вернуться в Arduino и другие Xduino

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2