поняли, но ничего не поняли
Цитата:
servo_pos++; я так понимаю 1 градус раз в 50мс
1 попугай почти раз в 50мс. после калибровки попугай может быть примерно и грудус. со временем и пониманием, как что работает, ещё хуже. т.е. ничего не изменилось, игрушку в стол/шкаф. к тому, что раньше написано ещё добавляется, что раз в голове не можете прикидывать, как работают и конкретные куски кода и всё в общем, так начинать можно хоть по старинке - отлаживать на бумажке или в табличном редакторе. в первом столбце описание какая стадия или событие. потом время, тики или ещё что, связанное со временем. а потом столбцы для переменных. как именно делать, вариантов масса.
не хотите вы эту бредятину с тупо линейной цикличностью и вычислениями даже не по времени или по предсказаниям погоды на марсе. в общем пока не видно даже намёка на желание прислушиваться и тем более сделать хотя бы простенькую скелетную анимацию, таймлайны, процедурное управление движениями. ну и ладно, дело ваше. вот набросок, почти на си (как минимум типы подрихтовать, может ещё чего) и может быть даже кое-как рабочий.
Код:
class Leg
{
private:
ulong startOn;
ulong cycleDuration_ms;
Servo s1;
Servo s2;
//start устанавливается меньше end
int degreeStart1;
int degreeStart2;
int degreeEnd1;
int degreeEnd2;
int degreeCurrent1;
int degreeCurrent2;
float degPerMs1;
float degPerMs2;
int s1CycleTime_ms;
int s2CycleTime_ms;
int direction; //1, -1
int thisCycleExeTime_ms;
int lastCycleExeTime_ms;
public:
Leg(int s1p, int s2p, ulong starton, ulong cycledur, int ds1, int ds2, int de1, int de2, int s1ct, int s2ct, int dir)
{
s1.attach(s1p);
s2.attach(s2p);
startOn = starton;
cycleDuration_ms = cycledur;
degreeStart1 = ds1;
degreeStart2 = ds2;
degreeEnd1 = de1;
degreeEnd2 = de2;
s1CycleTime_ms = s1ct;
s2CycleTime_ms = s2ct;
direction = dir;
lastCycleExeTime_ms = 0;
degPerMs1 = (degreeEnd1 - degreeStart1) / s1CycleTime_ms;
degPerMs2 = (degreeEnd2 - degreeStart2) / s2CycleTime_ms;
if (dir >= 0) direction = 1;
else direction = -1;
if (direction == 1)
{
degreeCurrent1 = degreeStart1;
degreeCurrent2 = degreeStart2;
}
else
{
degreeCurrent1 = degreeEnd1;
degreeCurrent2 = degreeEnd2;
}
s1.Write(degreeCurrent1);
s2.Write(degreeCurrent2);
}
void Tick(ulong currentTime)
{
if (currentTime < startOn) return;
thisCycleExeTime_ms = (int)(currentTime - (ulong)((currentTime - startOn) / cycleDuration_ms) * cycleDuration_ms);
if (lastCycleExeTime_ms > thisCycleExeTime_ms) direction *= -1;
lastCycleExeTime_ms = thisCycleExeTime_ms;
if (thisCycleExeTime_ms >= s1CycleTime_ms)
{
if (direction == 1) degreeCurrent1 = degreeEnd1;
else degreeCurrent1 = degreeStart1;
}
else
{
if (direction == 1) degreeCurrent1 = degreeStart1 + (int)(degPerMs1 * thisCycleExeTime_ms);
else degreeCurrent1 = degreeEnd1 - (int)(degPerMs1 * thisCycleExeTime_ms);
}
if (thisCycleExeTime_ms >= s2CycleTime_ms)
{
if (direction == 1) degreeCurrent2 = degreeEnd2;
else degreeCurrent2 = degreeStart2;
}
else
{
if (direction == 1) degreeCurrent2 = degreeStart2 + (int)(degPerMs2 * thisCycleExeTime_ms);
else degreeCurrent2 = degreeEnd2 - (int)(degPerMs2 * thisCycleExeTime_ms);
}
s1.Write(degreeCurrent1);
s2.Write(degreeCurrent2);
}
}
Leg leg1(пинсервы1, пинсервы2, 3000, 6000, 60, 60, 90, 120, 3000, 8000, 1); //8000, ой
Leg leg2(пинсервы1, пинсервы2, 6000, 4000, 60, 60, 90, 100, 4000, 4000, 1);
Leg leg3(пинсервы1, пинсервы2, 10000, 5000, 60, 60, 90, 110, 4000, 5000, 1);
Leg leg4(пинсервы1, пинсервы2, 14000, 6000, 60, 60, 90, 100, 6000, 6000, 1);
ulong time;
void loop()
{
time = mills();
leg1.Tick(time);
leg2.Tick(time);
leg3.Tick(time);
leg4.Tick(time);
delay(2);
}
пока на этом закончим, дальше от вас зависит.
п.с. и это, ещё раз - шестерни пластиковые. даже с железными при начальной отладке всякие лапы в воздухе должны болтаться.