Я проектирую и программирую похожий на лифт робот для проекта в средней школе. Могу ли я сделать что-нибудь, чтобы сделать это проще? Или лучше? Я приложил фотографию своего дизайна, которую я сделал в AutoCAD Inventor, с ярлыками.
Для тех, кто не знаком с RobotC или VEX (это ОЧЕНЬ похоже на C и C ++): концевые выключатели (limit1, limit2, …) и ударные выключатели (floor1, floor2, …) являются аналоговыми кнопками и возвращают значение 0, если не нажата, и 1, если нажата. Двигатель (mainMotor) вращает шестерню, которая заставляет механизм перемещаться вверх по суппорту. Когда торчащий вал двигателя движется вверх и вниз, он нажимает концевые выключатели и заставляет его возвращать значение 1.
int callup [3];
int calldown [3];
int floorat[3];
int main ()
{
if (SensorValue[limit1] == 1)
{
floorat[0] = 1;
}
else
{
floorat[0] = 0;
}
if (SensorValue[limit2] == 1)
{
floorat[1] = 1;
}
else
{
floorat[1] = 0;
}
if (SensorValue[limit3] == 1)
{
floorat[2] = 1;
}
else
{
floorat[2] = 0;
}
if (SensorValue[floor1] == 1)
{
calldown[0] = 1;
SensorValue[LED1] = 1;
}
if (SensorValue[floor2] == 1 && floorat[2] == 1)
{
calldown[1] = 1;
SensorValue[LED2] = 1;
}
if (SensorValue[floor2] == 1 && floorat[0] == 1)
{
callup[1] = 1;
SensorValue[LED2] = 1;
}
if (SensorValue[floor3])
{
callup[2] = 1;
SensorValue[LED3] = 1;
}
motors ();
}void motors ()
{
if (callup[2] == 1 && floorat[2] == 1)
{
int x = 1;
while (x < 3)
{
SensorValue[LED3] = 1;
wait(0.5);
SensorValue[LED3] = 0;
wait(0.5);
}
callup[2] = 0;
main ();
}
else if (callup[1] == 1 && floorat[1] == 1)
{
int x = 1;
while (x < 3)
{
SensorValue[LED2] = 1;
wait(0.5);
SensorValue[LED2] = 0;
wait(0.5);
}
callup[1] = 0;
main ();
}
else if (callup[0] == 1 && floorat[0] == 1)
{
int x = 1;
while (x < 3)
{
SensorValue[LED1] = 1;
wait(0.5);
SensorValue[LED1] = 0;
wait(0.5);
}
callup[0] = 0;
main ();
}
if (callup[2] == 1 && floorat[1] == 1 && calldown[0] == 0 || callup[2] == 1 && floorat[0] == 1 && callup[1] == 0)
{
startMotor(mainMotor, 60);
untilTouch(limit3);
stopMotor(mainMotor);
callup[2] = 0;
wait(1);
main ();
}
if (callup[1] == 1 && floorat[0] == 1)
{
startMotor(mainMotor, 60);
untilTouch(limit2);
stopMotor(mainMotor);
callup[1] = 0;
wait(1);
main();
}
if (calldown[1] == 1 && floorat[2] == 1)
{
startMotor(mainMotor, -60);
untilTouch(limit2);
stopMotor(mainMotor);
calldown[1] = 0;
wait(1);
main();
}
if (calldown[0] == 1 && floorat[2] == 1 && calldown[1] == 0 || calldown[0] == 1 && floorat[1] == 1)
{
startMotor(mainMotor, -60);
untilTouch(limit1);
stopMotor(mainMotor);
calldown[0] = 0;
wait(1);
main();
}
}
Хотя этот вопрос не должен волновать, значение 60 в команде startMotor — это скорость двигателя, чтобы сделать его более понятным.
Не стесняйтесь задавать больше вопросов.
Я не знаком с RobotC или VEX, однако я заметил определенное количество реплицированных операций, которые могут быть превращены в их собственные функции.
Следующий фрагмент кода я бы сделал в отдельных функциях. Итак, в большой функции, называемой двигателями, у вас есть следующий набор операций:
int x = 1;
while (x < 3)
{
SensorValue[LED3] = 1;
wait(0.5);
SensorValue[LED3] = 0;
wait(0.5);
}
callup[2] = 0;
main ();
Это повторяется с немного другими значениями.
Здесь я бы написал функцию, подобную следующей:
void adjust_sensors( size_t led, size_t level )
{
int x = 1;
while (x < 3)
{
SensorValue[led] = 1;
wait(0.5);
SensorValue[led] = 0;
wait(0.5);
}
callup[level] = 0;
main ();
}
Вы можете сделать то же самое для следующего кода:
startMotor(mainMotor, 60);
untilTouch(limit3);
stopMotor(mainMotor);
callup[2] = 0;
wait(1);
main ();
Также кажется, что цикл while никогда не закончится, потому что значение x никогда не меняется.
У вас также есть опечатка наверху, когда вы объявляете:
int callown [2];
Я полагаю, вы имели в виду:
int calldown [2];
Было бы неплохо добавить некоторые комментарии к вашему коду, а также для ясности.
Надеюсь это поможет.
Давайте определим, каковы состояния лифта в данный момент:
Лифт может пойти вверх, вниз, или быть вхолостую.
Лифт находится на заданном этаж и перейти с одного этажа на другой, когда он активирует переключатель:
Теперь, если мы переведем это в некоторый псевдокод (который должен быть легко переведен на RobotC
):
enum elevator_status = { idle, down, up };
int currentfloor; //1, 2, 3switch(elevator_status)
{
case idle:
//we check if a button is pressed and possibly go up or down
if(SensorValue(floor1))
{
if(currentfloor > 1)
elevator_status = down;
}
else if(SensorValue(floor2))
{
if(currentfloor > 2)
elevator_status = down;
else if(currentfloor < 2)
elevator_status = up;
}
else if(SensorValue(floor3))
{
if(currentfloor < 3)
elevator_status = up;
}
break;
case up:
case down:
//we check if we trigger a floor switch and stop the elevator
if(SensorValue(limit1))
{
currentfloor = 1;
elevator_status = idle;
}
else if(SensorValue(limit2))
{
currentfloor = 2;
elevator_status = idle;
}
else if(SensorValue(limit3))
{
currentfloor = 3;
elevator_status = idle;
}
break;
}//we set the speed of the motor
if(elevator_status == up)
{
set_motorstate(cw);
)
else if(elevator_status == down)
{
set_motorstate(ccw);
}
else if(elevator_status == idle)
{
set_motorstate(idle);
}
Примечание: в этом коде лифт будет заботиться о новых вызовах вверх и вниз по этажу, когда лифт простаивает. Он не сохраняет вызовы вверх и вниз во время движения и отправляется туда позже. Я не знаю, было ли это требованием для вас.
Я мог бы быть далеко, потому что я просто студент с моими собственными вопросами, но, похоже, вы допустили ошибку в ваших размерах массива. Например, когда вы объявили:
int floorat[2];
Это сделало массив размером 2. Затем вы ссылаетесь на 3 расположения элементов в этом массиве [0, 1, 2]. Кроме того, вы не можете просто использовать обычное целое число и присвоить ему значения 1, 2 или 3?
Я бы порекомендовал переопределить эти переменные как:
int callup;
int calldown;
int floorat;
Тогда вы можете избежать лишних строк кода и упростить предложения if / else:
if (SensorValue[limit1] == 1)
{
floorat = 1;
}
if (SensorValue[limit2] == 1)
{
floorat = 2;
}if (SensorValue[limit3] == 1)
{
floorat = 3;
}