Технический форум по робототехнике.
getbraine » 11 июн 2010, 00:01
Что нужно сделать:
Есть элементы GUI (5ть кнопок : вперед ,назад ,влево ,вправо ,стоп) и текстовое поле ,куда будут заноситься результаты выполнения команд(если пользователь нажал кнопку "вперед" ,то в текстовое поле пишется "движение вперед"). Нужно реализовать следующее ,если пользователь,например , нажал кнопку "вперед" ,то в текстовое поле пишется "движение вперед" до тех пор ,пока не нажата кнопка "стоп".
пытался реализовать этот алгоритм с помощью тредов . Вот что получилось :
- Код: Выделить всё • Развернуть
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace ArduinoProject
{
public partial class myForm : Form
{
public int cycleNumber;
void sendCommands(string commandName)
{
CheckForIllegalCrossThreadCalls = false;
myTextBox.Text += commandName;
CheckForIllegalCrossThreadCalls = true;
}
private void selectSycle()
{
//for (; ; )
{
switch (cycleNumber)
{
default:
break;
case 1:
sendCommands("move forward");
break;
case 2:
sendCommands("mowe back");
break;
case 3:
sendCommands("turn right");
break;
case 4:
sendCommands("turn left");
break;
}
}
}
public myForm()
{
InitializeComponent();
Thread Syclerun = new Thread(new ThreadStart(selectSycle));
Syclerun.Start();
}
private void moveForward_Click(object sender, EventArgs e)
{
cycleNumber=1;
selectSycle();
}
private void turnLeft_Click(object sender, EventArgs e)
{
cycleNumber=2;
selectSycle();
}
private void turnRight_Click(object sender, EventArgs e)
{
cycleNumber=3;
selectSycle();
}
private void moveBack_Click(object sender, EventArgs e)
{
cycleNumber=4;
selectSycle();
}
private void Pause_Click(object sender, EventArgs e)
{
}
}
}
недостаток этого кода заключается в том ,что форма быстро заполняется текстом (например ,если я нажал кнопку "вперед" ,то текстом "движение вперед") ,при этом никакие
- Код: Выделить всё • Развернуть
System.Threads.Sleep()
не помогают (максимум к чему данная конструкция приводит - в поле не выводятся результаты нажатия кнопок).
Angel71 » 11 июн 2010, 10:56

совсем не прикольно. смотри в доке , что такое +=
П.С. студия отлично реагирует на пимпы F5, F6, F9, F10, F11. ну или тоже самое из меню и тулбаров. зачем доп. поток, который сразу же "сдыхает"? зааачем ...?
getbraine » 11 июн 2010, 12:36
совсем не прикольно. смотри в доке , что такое +=
я знаю ,что такое операция += . дело не в ней. я думаю ,что с тредами накосячил.не умею я с ними работать=)
- Код: Выделить всё • Развернуть
П.С. студия отлично реагирует на пимпы F5, F6, F9, F10, F11. ну или тоже самое из меню и тулбаров. зачем доп. поток, который сразу же "сдыхает"? зааачем ...
что ты имел ввиду ?я не знаю ,как по другому это реализовать . any ideas?
Angel71 » 11 июн 2010, 14:52
getbraine писал(а):если пользователь,например , нажал кнопку "вперед" ,то в текстовое поле пишется "движение вперед" до тех пор ,пока не нажата кнопка "стоп".
getbraine писал(а):недостаток этого кода заключается в том ,что форма быстро заполняется текстом (например ,если я нажал кнопку "вперед" ,то текстом "движение вперед") ,при этом никакие
- Код: Выделить всё • Развернуть
System.Threads.Sleep()
не помогают (максимум к чему данная конструкция приводит - в поле не выводятся результаты нажатия кнопок).

если знаете, должны понимать разницу между нужным "=" для "пишется" и "+=" для "дописывать". или я не понимаю описание в первом посте или еще что. с потоками ситуация не лучше. во первых их у вас реально нет (он запускается и сразу же прекращает работу).

и при чём тут потоки? во вторых если вы расскоментируете заголовок цикла, то у вас получится полный писец. в третьих резонный вопрос - а нужны ли в данном случае, эти потоки вообще?
getbraine писал(а):что ты имел ввиду ?я не знаю ,как по другому это реализовать . any ideas?
отладку.
если есть желание - опишите задачу более ясно, тогда смогу помочь. то, как описано сейчас мне мало понятно и создаётся ощущение, что мы говорим о разных вещах.
getbraine » 11 июн 2010, 15:11
Спасибо за ответ!
попытаюсь более детально описать исходную задачу
Есть 5 кнопок ,которые управляют движением робота : вперед ,назад ,влево ,вправо ,стоп. Рассмотрим ситуацию когда пользователь нажимает кнопку вперед: после того как кнопка "вперед" нажата ,робот должен двигаться вперед ,до тех пор пока не нажата какая-либо другая кнопка ,если нажата другая кнопка (например кнопка "влево") ,то робот должен остановиться и повернуть налево.
Что я подразумеваю под выражениями ,"робот должен ехать вперед" ,"робот должен повернуть налево" и т.д. :
-если робот едет вперед ,то в текстовое поле пишется "робот движется вперед" (произвольное число раз)
-если робот едет назад ,то в текстовое поле пишется "робот движется назад" (произвольное число раз)
-если робот повернул направо ,то в текстовое поле пишется (1 раз!!!!) "робот повернул направо"
-если робот повернул налево ,то в текстовое поле пишется (1 раз!!!!) "робот повернул налево"
-если робот остановился ,то в текстовое поле пишется (1 раз!!!!) "робот остановился"
если есть вопросы ,то задавайте.
Angel71 » 11 июн 2010, 15:57
примерно так
- Код: Выделить всё • Развернуть
private void selectSycle()
{
while(true)
{
switch (cycleNumber)
{
default:
break;
case 1:
sendCommands("move forward");
break;
case 2:
sendCommands("mowe back");
break;
}
//Thread.Sleep(0);//спать следующего кванта
Thread.Sleep(1000);//спать секунду
}
}
выкидываете из обработчиков кнопок вызов selectSycle()
обработчики кнопок "влево", "вправо", "стоп", "пауза" меняете примерно так
- Код: Выделить всё • Развернуть
private void turnLeft_Click(object sender, EventArgs e)
{
cycleNumber=2;
sendCommands("turn left");
}

а так... здесь скорей всего вся логика программы не корректна
Ku6opr » 11 июн 2010, 16:03
Создаете поток:
Thread Syclerun = new Thread(new ThreadStart(selectSycle));
Syclerun.Start();
А ниже вызов selectSycle() еще при каждом нажатии, т.е. дополнительный поток тут просто не нужен.
Если вам нужно, чтоб выводило "едем вперед" через какие-то интервалы времени, когда робот едет вперед, то используйте таймер.
Например:
string Out; // То, что будем выводить по таймеру
Out = "едем вперед"; // присваиваем, когда едем вперед
sendCommands("move forward");
Out = ""; // очищаем, когда ничего выводить не нужно
sendCommands("turn right");
Тело таймера
{
myTextBox.Text += Out; // Выводим фразу, которую присвоили выше
}
Angel71 » 11 июн 2010, 16:06
да, кстати, про selectSycle (так же как и в варианте с таймерами от Ku6opr) это в корне не верно так делать, но... какие условия, такой и ответ
getbraine » 11 июн 2010, 19:33
может ,подскажите , как бы вы решили данную задачу?
АПД: сделал с помощью таймера ,то что мне нужно
- Код: Выделить всё • Развернуть
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace ArduinoProject
{
public partial class myForm : Form
{
public int cycleNumber=-1;
bool activated;//начало работы таймера
bool bMoveForwardClicked;//нажата ли кнопка движения вперед
bool bMoveBackClicked;//нажата ли кнопка движения назад
bool bTurnRightClicked;//нажата ли кнопка поврота направо
bool bTurnLeftClicked;//нажата ли кнопка поворота налево
bool bStopClicked;//нажата ли кнопка стоп
void sendCommands(string commandName)
{
myTextBox.Text += commandName;
}
public myForm()
{
InitializeComponent();
}
private void moveForward_Click(object sender, EventArgs e)
{
//sendCommands("move forward");
activated = true;
bMoveForwardClicked = true;
bMoveBackClicked = false;
}
private void turnLeft_Click(object sender, EventArgs e)
{
sendCommands("turn left");
}
private void turnRight_Click(object sender, EventArgs e)
{
sendCommands("turn right");
}
private void moveBack_Click(object sender, EventArgs e)
{
//sendCommands("move back");
activated = true;
bMoveBackClicked = true;
bMoveForwardClicked = false;
}
private void Pause_Click(object sender, EventArgs e)
{
//selectSycle();
activated = false;
}
private void myTimer_Tick(object sender, EventArgs e)
{
if (activated)
{
if (bMoveForwardClicked)
{
sendCommands("forward");
}
else
{
sendCommands("back");
}
}
}
}
}
спасибо киборгу!
Angel71 » 11 июн 2010, 20:33
нет интерфейса общения с гипотетическим роботом, без этого никак. предпологаю, что он не программый (тогда вмиг умываю руки), а аппаратный - минибот или ещё что, не важно.
допустим команда "вперёд", это как? один раз отослал и он едет и едет, до тех пор, пока не отправишь другую команду? или это его с каким-то интервалом нужно что-то отправлять, а с каким и зачем так? или ещё как?
зачем в текст боксе текст добавлять, да и текстбокс зачем? лэйбл.текст = "название команды" вполне справится, будет отображаться название последней команды. если прям хочется в случае поворота отображать сначала "поворачиваю", а затем "остановился", то тоже непонятно как делать. одно дело, если вы должны только отослать "поворачивай". другое - сначала "поворачивай", а затем, спустя какое-то время "стоп".
необходимость в потоках пока под вопросом.
getbraine » 11 июн 2010, 20:52
один раз отослал и он едет и едет, до тех пор, пока не отправишь другую команду?
именно так как вы написали . я это уже реализовал с помощью таймера ,думаю задачу можно снимать с обсуждения
Ku6opr » 12 июн 2010, 14:13
Angel71 имеет в виду, что в функции sendCommands будет еще и отправление роботу команды, а не только вывод строки на экран. Поэтому по таймеру нужно вызывать не sendCommands, а просто вывод на экран (чтоб роботу не приходила одна и та же команда раз в секунду)
Angel71 » 12 июн 2010, 14:45

начиная с момента "+=" особого значения ничего уже не имеет. это не тесты, когда сознательно вводишь грубейшие ошибки, чтоб посмотреть как поведут себя какие-то компоненты или часть кода или софтина в целом.