реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Движение деревянного круга, налево и направо
Andrei Aleksandr...
сообщение Sep 18 2008, 03:26
Сообщение #1





Группа: Новичок
Сообщений: 2
Регистрация: 21-04-08
Пользователь №: 36 974



Задача имеется такая smile.gif

Есть круг, размеченный на секторы - от 0 до 15. Он крутится. Можно выбрать любой текущий ("для работы") сектор. Например, мы находимся сейчас на секторе номер пять и нам нужно перейти на сектор номер дестяь. Мы прокручиваем круг на пять секторов, допустим, вправо. Но если текущий сектор пять, а мы хотим перейти на третий, то если бы прокрутили в ту же сторону, то пришлось бы прокручивать всю остальную часть круга, прежде чем перейти на нужный - третий.

Экономичнее было бы прокрутить круг налево - и очутится на номере три уже через два сектора. Но как я могу определить, в какую сторону мне экономичнее крутить - налево или направо? Если даны две данных - номер текущего сектора и номер сектора, на который следует перейти.
Go to the top of the page
 
+Quote Post
=GM=
сообщение Sep 19 2008, 09:31
Сообщение #2


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Вычисляете разности (n-m) и (m-n) по модулю 16, сравниваете их и крутите по меньшему. Например,

1) (5-3)mod16=2, (3-5)mod16=-2+16=14, 2<14 - крутите влево.
2) (5-10)mod16=-5+16=11, (10-5)mod16=5, 11>5 - крутите вправо.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
ReAl
сообщение Sep 19 2008, 14:45
Сообщение #3


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(=GM= @ Sep 19 2008, 12:31) *
Вычисляете разности (n-m) и (m-n) по модулю 16, сравниваете их и крутите по меньшему. Например,
1) (5-3)mod16=2, (3-5)mod16=-2+16=14, 2<14 - крутите влево.
2) (5-10)mod16=-5+16=11, (10-5)mod16=5, 11>5 - крутите вправо.
А зачем вычислять вторую, она ведь жёстко связана с первой, новой информации не несёт.
Достаточно сравнивать с половиной количества

Код
(5-3) mod 16 = 2
2 <= (16 div 2) истинно - крутите влево.

(5-10) mod 16 = -5+16 = 11
11 <= (16 div 2) - ложно - крутите вправо


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
Andrei Aleksandr...
сообщение Sep 20 2008, 03:50
Сообщение #4





Группа: Новичок
Сообщений: 2
Регистрация: 21-04-08
Пользователь №: 36 974



Цитата(=GM= @ Sep 19 2008, 11:31) *
Вычисляете разности (n-m) и (m-n) по модулю 16, сравниваете их и крутите по меньшему. Например,

1) (5-3)mod16=2, (3-5)mod16=-2+16=14, 2<14 - крутите влево.
2) (5-10)mod16=-5+16=11, (10-5)mod16=5, 11>5 - крутите вправо.


Как я написал на Си:

Код
void set_motor1(signed char position)  // аргумент - номер шприца, на который переход
{
signed char k = 0;
signed char s1,s2 = 0;
k = current_position(); // в к находится текущая позиция шприца
  
PORTC.7 = 1; //
ес
spritze_to_set = position-1; //вводим в переменную номер, на какой переходим от 0 до 15

s1 = ((k - position) % 16);        
s2 = (position - k)  % 16;

if (s1 <= s2) motor_control(1,2);  //  мотор в одну сторону
else motor_control(1,1);                // мотор в другую сторону


}


В переходах между, например, 1 и 3 - нормально, а между 1 и 2 - уже крутит в неправильную сторону (тоесть прокручивает полностью круг, чтобы добраться до позиции). Что я делаю не так? smile.gif
Go to the top of the page
 
+Quote Post
ReAl
сообщение Sep 20 2008, 06:43
Сообщение #5


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(Andrei Aleksandrovich @ Sep 20 2008, 06:50) *
В переходах между, например, 1 и 3 - нормально, а между 1 и 2 - уже крутит в неправильную сторону (тоесть прокручивает полностью круг, чтобы добраться до позиции). Что я делаю не так? smile.gif

Вы не поняли, как считать расстояния, в одну из сторон они у Вас выходят отрицательными (и смещёнными). Надо так (len - длина всего круга, остальные переменные тоже с осмысленными именами):
Код
    forward_dist = (to - current) % len;
    if(forward_dist < 0) forward_dist += len;
    backward_dist = (current - to)  % len;
    if(backward_dist < 0) backward_dist += len;

    if(forward_dist <= backward_dist) {
        ...

Если учесть моё замечание про жёсткую связь между forward_dist и backward_dist, то
Код
    forward_dist = (to - current) % len;
    if(forward_dist < 0) forward_dist += len;
    backward_dist = len - forward_dist;

    if(forward_dist <= backward_dist) {
        ...

Но тогда непонятно, зачем вообще вычислять backward_dist, если можно так, как я сразу сказал:
Код
    half_len = len/2; // ну или константа, равная половине константы len
    ...
    forward_dist = (to - current) % len;
    if(forward_dist < 0) forward_dist += len;
    if(forward_dist <= half_len) {
        ...

Собственно, если исходно есть гарантия, что и to и current находятся в диапазоне 0..(len-1), то вычисление остатка не нужно вообще:
Код
    half_len = len/2;
    ...
    forward_dist = to - current;
    if(forward_ist < 0) forward_dist += len;
    if(forward_dist <= half_len) {
        ...

А для конкретной фиксированной длины 16 (степень двойки) можно вообще так:
Код
#define LEN 16

#if LEN < 2 || ( LEN & (LEN-1) ) != 0
#error "LEN must be power of 2 and >= 2"
#endif

#define HALF_LEN (LEN/2)
#define MASK (LEN-1)
    ...
    forward_dist = (to - current) & MASK;
        // или ниже вообще if( !(forward_dist & HALF_LEN) ) {
        // так как HALF_LEN тоже степень двойки и есть маской старшего бита расстояния
        // только обозвать тогда тоже нужно  вразумительнее, скажем, HALF_LEN_MASK
    if(forward_dist <= HALF_LEN) {
        // go forward
    } else {
        // go backward
    }


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
Валентиныч
сообщение Sep 22 2008, 05:30
Сообщение #6


Профессионал
****

Группа: Свой
Сообщений: 553
Регистрация: 17-02-05
Из: Свердловская обл.
Пользователь №: 2 712



Цитата(Andrei Aleksandrovich @ Sep 18 2008, 09:26) *
Есть круг, размеченный на секторы - от 0 до 15. Он крутится.
...
Экономичнее было бы прокрутить круг налево - и очутится на номере три уже через два сектора. Но как я могу определить, в какую сторону мне экономичнее крутить - налево или направо?

О какой "экономичности" идет речь?
Если круг "крутится", то однозначно - экономичнее не реверсировать движение (потери на останов/разгон), а сделать лишних n-шагов. Да и само устройство с реверсом вращения обойдется дороже, будет сложнее (как следствие - менее надежно), чем простой привод шагового поворота.
ИМХО - вращать только в одну сторону. Много на 5-7 (даже на 15!) лишних шагах не потеряете. Тем более, что очевидна не высокая "скорострельность" устройства.


--------------------
Закономерность: Чем больше узнаю, тем меньше знаю...
Любые мнения, даже ошибочные, имеют право на существование.
Чем лучше узнаю людей, тем больше нравятся собаки...
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 01:11
Рейтинг@Mail.ru


Страница сгенерированна за 0.01409 секунд с 7
ELECTRONIX ©2004-2016