Округление

exez
exez аватар
Offline
Зарегистрирован: 04.04.2015

Возникла проблема с обработкой синусов и косинусов.

к примеру

    d1 = 55*cos(x*.01745);         if (d1 < 0) { d1 = -d1;}// if (d2 > 30) {d2 = 30;}
    d2 = 55*sin(x*.01745) ;         if (d2 < 0) { d2 = -d2;}// if (d4 > 30) {d4 = 30;}
 
    x++ ; if (x > 360) { x = 0; }
 
в граничных точках. 0, 90, 180, 270 градусов результаты синуса и косинуса дают значения близкие к 0 и единице, а общая картина выглядит примерно так:
 
   x = 70   d1 = 19   d2 = 51
   x = 71   d1 = 18   d2 = 51
   x = 72   d1 = 17   d2 = 51
   x = 73   d1 = 17   d2 = 52
   x = 74   d1 = 16   d2 = 52
   x = 75   d1 = 15   d2 = 52
   x = 76   d1 = 14   d2 = 53
   x = 77   d1 = 13   d2 = 53
   x = 78   d1 = 12   d2 = 53
   x = 79   d1 = 11   d2 = 53
   x = 80   d1 = 10   d2 = 53
   x = 81   d1 = 9   d2 = 54
   x = 82   d1 = 8   d2 = 54
   x = 83   d1 = 7   d2 = 54
   x = 84   d1 = 6   d2 = 54
   x = 85   d1 = 5   d2 = 54
   x = 86   d1 = 4   d2 = 54
   x = 87   d1 = 3   d2 = 54
   x = 88   d1 = 2   d2 = 54
   x = 89   d1 = 1   d2 = 54
   x = 90   d1 = 0   d2 = 54
   x = 91   d1 = 0   d2 = 54
   x = 92   d1 = 0   d2 = 54
   x = 93   d1 = 1   d2 = 54
   x = 94   d1 = 2   d2 = 54
   x = 95   d1 = 3   d2 = 54
   x = 96   d1 = 4   d2 = 54
   x = 97   d1 = 5   d2 = 54
   x = 98   d1 = 6   d2 = 54
   x = 99   d1 = 7   d2 = 54
   x = 100   d1 = 8   d2 = 54
   x = 101   d1 = 9   d2 = 54
   x = 102   d1 = 10   d2 = 53
   x = 103   d1 = 11   d2 = 53
   x = 104   d1 = 12   d2 = 53
   x = 105   d1 = 13   d2 = 53
   x = 106   d1 = 14   d2 = 53
   x = 107   d1 = 15   d2 = 52
   x = 108   d1 = 16   d2 = 52
   x = 109   d1 = 16   d2 = 52
   x = 110   d1 = 17   d2 = 52
 
а мне бы получить 55 в пиковых значениях (к примеру с 87 градусов до 94)... как это сделать?

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Полностью скетч привести не судьба? Как описаны d1, d2?

Если int, просто добавьте + 0.5 после закрывающей скобки cos 

 d1 = 55*cos(x*.01745) +0.5;

exez
exez аватар
Offline
Зарегистрирован: 04.04.2015
const int motorPin1 = 2;
const int motorPin2 = 3;
const int motorPin3 = 4;
const int motorPin4 = 5;




 int      d1, d2; 
 float    Rad = .01745;
 float    xx = 0;
 int      w = 55;                   // мощность ШИМ от 0 до 255;
 int      motorDelayML = 50;         // millis()
 int      motorDelayMS = 0;       // micro

 
 int x;

 
void setup() {                



    pinMode(motorPin1, OUTPUT);    
    pinMode(motorPin2, OUTPUT);    
    pinMode(motorPin3, OUTPUT);    
    pinMode(motorPin4, OUTPUT);     

  Serial.begin(9600);
}
 
void loop() {

      if ( x >= 0 && x < 90 )
      {
    digitalWrite(  motorPin1, LOW  );
    digitalWrite(  motorPin2, HIGH );
    digitalWrite(  motorPin3, HIGH );
    digitalWrite(  motorPin4, LOW  );
      }
       
      if ( x >= 90 && x < 180 )
      {
    digitalWrite(  motorPin1, HIGH );
    digitalWrite(  motorPin2, LOW  );
    digitalWrite(  motorPin3, HIGH );
    digitalWrite(  motorPin4, LOW  ); 
      }

      if ( x >= 180 && x < 270)
      {
    digitalWrite(  motorPin1, HIGH );
    digitalWrite(  motorPin2, LOW  );
    digitalWrite(  motorPin3, LOW  );
    digitalWrite(  motorPin4, HIGH );   
      }

      if ( x >= 270 && x < 360)
      {
    digitalWrite(  motorPin1, LOW  ); 
    digitalWrite(  motorPin2, HIGH );
    digitalWrite(  motorPin3, LOW  );
    digitalWrite(  motorPin4, HIGH );  
      }

    x = x + 1 ; if (x > 360) { x = 0; }
    d1 = w*cos(x*Rad) + xx;         if (d1 < 0) { d1 = -d1;}
    d2 = w*sin(x*Rad) + xx;         if (d2 < 0) { d2 = -d2;}
    if (x > 355  && x < 360 || x > 0  && x < 5 || x > 175 && x < 185) {d1 = d1 + 1;}
    if (x > 85  && x < 95 || x > 265 && x < 275) {d2 = d2 + 1;}
    analogWrite(10, d1);
    analogWrite(11, d2);
    
    delay(motorDelayML);
    delayMicroseconds(motorDelayMS);

    Serial.print("   x = ");Serial.print(x);    Serial.print("   d1 = ");Serial.print(d1);    Serial.print("   d2 = ");Serial.println(d2);
 
}

 

exez
exez аватар
Offline
Зарегистрирован: 04.04.2015

в данный момент борюсь тупо сравнивая градус с критическими значениями и плюсую 1.. но при таком раскладе не получится правильно отрабатывать движение, если к примеру параметр W увеличить..

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, я уже написал что сделать, если они int (а они int). Делайте.

exez
exez аватар
Offline
Зарегистрирован: 04.04.2015

Спасибо Евгений. в моем случае подошло значение хх = .1

 

:)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

exez пишет:

Спасибо Евгений. в моем случае подошло значение хх = .1

0.1 - это ошибка. Правильно использовать 0.5

И это верно не только для конечных значений, а для всех.

Преобразование к целому делается путём ОТБРАСЫВАНИЯ дробной части, поэтому, если у Вас получасется 1.2, 1.3 или 1.9 - в любом случае результат 1.

Использование 0.5 как раз и даёт то, что если получилось меньше половинки, то округлится вниз, а если больше - то вверх.

А Ваша 0.1 спасает только для крайних положений (когда близко к 1). А если, допустим результат 1.8, то с вашей 0.1 после окргугления будет 1, а не 2.