=DeaD= писал(а):Какую точность оно у вас даёт? Плавные движения уже реализовали? Без них будет полный кирдык
Надеюсь что реализовал
 Пока сервы не получу на руки, могу только предполагать. Приращения скорости использую  пока линейные. Проще наверно исходники показать, чем сто раз объяснять
 Пока сервы не получу на руки, могу только предполагать. Приращения скорости использую  пока линейные. Проще наверно исходники показать, чем сто раз объяснять  Сразу предупреждаю, баги присутствуют, код в процессе разработки.
 Сразу предупреждаю, баги присутствуют, код в процессе разработки.- Код: Выделить всё • Развернуть
- //attempt at using the Axon and Axon II as a servo controller
 //define how data should be sent (choose only one)
 //#define U0
 #define USB
 //declare microcontroller
 //#define AXON
 #define AXON2
 #define DEBUG
 //WebbotLib Includes
 #ifdef AXON
 #include "sys/axon.h"
 #endif
 #ifdef AXON2
 #include "sys/axon2.h"
 #endif
 //#include "buffer.h"
 #include "iopin.h"
 #include "timer.h"
 #include "rprintf.h" //use for UART
 #include "inttypes.h"
 //UART defines (name your UART)
 #define U0_UART UART0
 #define USB_UART UART1
 //UART baud defines (change baud rate)
 #define U0_BAUD (BAUD_RATE)230400
 #define USB_BAUD (BAUD_RATE)230400
 //UART define which uart to use
 #define U0_ACTIVATE &uart0SendByte
 #define USB_ACTIVATE &uart1SendByte
 //getting data
 #define GET_DATA_U0 uart0GetByte()
 #define GET_DATA_USB uart1GetByte()
 //create a big buffer for UART
 #ifdef U0
 #define UART0_RX_BUFFER_SIZE 100
 #endif
 #ifdef USB
 #define UART1_RX_BUFFER_SIZE 100
 #endif
 #include "hardware.h" //declare your servo and sensor ports here
 int8_t lastByte=-1; //store last recieved character
 //lastByte = -1;
 int8_t buff_array[100]; //store last command
 uint8_t buff_pos=0; //record current position in array
 uint8_t buff_read=0; //record current position in array
 boolean command_received=0; //active last command
 SERV *serva[32];
 int count_us;
 enum command_state commst=empty;
 void save_move(uint8_t *channel, uint16_t *pulsewidth, uint16_t *speed, uint16_t *time)
 {
 if (*pulsewidth)
 {
 for(int i=0; i<32; i++)
 {
 if (serva[i]->channel == *channel)
 {
 if (*time)
 {
 long int tbs;
 if (serva[i]->target > serva[i]->posnow)
 {
 tbs = (serva[i]->target - serva[i]->posnow) / *time * 1000;
 } else {
 tbs = (serva[i]->posnow - serva[i]->target) / *time * 1000;
 }
 if (tbs < *speed)
 {
 *speed = tbs;
 }
 }
 serva[i]->target = *pulsewidth;
 serva[i]->speed = *speed;
 rprintf("Parsed command: channel %d, target %d, speed %d,\n", *channel, *pulsewidth, *speed);
 }
 }
 *channel=0;
 *pulsewidth=0;
 *speed=0;
 }
 }
 //initialize hardware, ie servos, UART, etc.
 void appInitHardware(void)
 {
 #ifdef AXON2
 led_off();
 #endif
 
 //setup UART0 or USB
 #ifdef USB
 uartInit(USB_UART, USB_BAUD);
 rprintfInit(USB_ACTIVATE);
 #endif
 #ifdef U0
 uartInit(U0_UART, U0_BAUD);//bluetooth
 rprintfInit(U0_ACTIVATE);
 #endif
 
 for (int i; i<32;i++) //init servo data
 {
 //serva[i] = &(SERV);
 serva[i]->channel = i;
 serva[i]->target = 1500;
 serva[i]->posnow = 1500;
 serva[i]->speed = 0;
 }
 
 }
 TICK_COUNT appInitSoftware(TICK_COUNT loopStart)
 {
 rprintf("init\n");
 count_us = clockGetus();
 return 0;
 }
 
 // This is the main loop
 TICK_COUNT appControl(LOOP_COUNT loopCount, TICK_COUNT loopStart)
 {
 ////////////GET COMMAND/////////////
 #ifdef USB
 lastByte=GET_DATA_USB;
 #endif
 #ifdef U0
 lastByte=GET_DATA_U0;
 #endif
 //fill up array with command recieved from UART
 if(lastByte!=-1)//has new data
 {
 buff_array[buff_pos]=lastByte;
 buff_pos++;
 if(lastByte == 0x0d)//if command is finished
 command_received=1;
 }
 //when command is received, parse it
 if(command_received)
 {
 uint8_t incoming_channel=0;
 uint16_t incoming_pulsewidth=0;
 uint16_t incoming_speed=0;
 uint16_t incoming_time=0;
 commst = empty;
 rprintf("Command received:");
 rprintfMemoryDump(buff_array, 0, buff_pos);
 rprintf("\n");
 //look for 'T' command first
 buff_read=0;
 while(buff_read <= buff_pos)
 {
 if (buff_array[buff_read] == 'T' || buff_array[buff_read] == 't')
 {
 commst = time;
 } else {
 if (commst == time)
 {
 incoming_time = incoming_time * 10 + (buff_array[buff_read] & 0x0F);
 } else {
 commst = empty;
 }
 }
 buff_read++;
 }
 
 //while the full array hasn't been read yet
 //parse the rest of commands
 buff_read=0;
 while(buff_read<=buff_pos)
 {
 if (buff_array[buff_read] > 0x2F && buff_array[buff_read] < 0x3A && commst )
 {
 switch (commst)
 {
 case channel:
 incoming_channel = incoming_channel * 10 + (buff_array[buff_read] & 0x0F);
 break;
 case pulsewidth:
 incoming_pulsewidth = incoming_pulsewidth * 10 + (buff_array[buff_read] & 0x0F);
 break;
 case speed:
 incoming_speed = incoming_speed * 10 + (buff_array[buff_read] & 0x0F);
 break;
 case time: case empty: case positionoffset:
 break;
 }
 } else {
 switch (buff_array[buff_read])
 {
 case 0x0d:
 save_move(&incoming_channel, &incoming_pulsewidth, &incoming_speed, &incoming_time);
 break;
 case '#':
 save_move(&incoming_channel, &incoming_pulsewidth, &incoming_speed, &incoming_time);
 commst = channel;
 break;
 case 'P': case 'p':
 commst = pulsewidth;
 break;
 case 'S': case 's':
 commst = speed;
 break;
 case 'T': case 't':
 commst = empty;
 break;
 default:
 commst = empty;
 }
 }
 buff_read++;
 }
 buff_pos=0;//reset array
 command_received=0;
 }
 
 // send pulses to servos every 18 ms
 if (clockHasElapsed(count_us, 18000))
 {
 count_us = clockGetus();
 rprintf("Time is: %d\n", count_us);
 
 //define short-term target for each servo
 long int pos = 0;
 for (int i; i<32;i++)
 {
 pos = serva[i]->posnow;
 if (serva[i]->target > pos)
 {
 pos += serva[i]->speed/50;
 if (pos > serva[i]->target) pos = serva[i]->target;
 } else {
 pos -= serva[i]->speed/50;
 if (pos < serva[i]->target) pos = serva[i]->target;
 }
 serva[i]->posnow = pos;
 }
 //sort servos ascending by short-term target
 int isDone=0;
 SERV *tmp;
 for (int i=0;(i<32-1)&&(!isDone);i++)
 {
 isDone=1;
 for (int j=0;j<32-i-1;j++)
 {
 if (serva[j]->posnow > serva[j+1]->posnow)
 {
 // keep number and port in sync with the position so we know which port to change!
 tmp = serva[j];
 serva[j] = serva[j+1];
 serva[j+1] = tmp;
 isDone=0;
 }
 }
 }
 //*tmp = 0;
 
 #ifdef DEBUG
 for (int i; i<32;i++)
 {
 rprintf("Servo state: order: %d, channel: %d, target: %d, posnow: %d, speed: %d", i, serva[i]->channel, serva[i]->target, serva[i]->posnow, serva[i]->speed);
 }
 #endif
 cli(); //block interrupts
 
 // put all servos' pin to high
 for (int i; i<32;i++)
 {
 pin_high(serva[i]->pin);
 }
 
 // put pins low based on short-term target
 int offset=0;
 for (int i=0;i<32;i++)
 {
 pos = serva[i]->posnow;
 if (pos > 0)
 {
 if (pos > offset)
 {
 // wait until this servo's position offset
 delay_us(pos - offset);
 offset = pos;
 }
 // turn off this servo and continue with next servos
 pin_low(serva[i]->pin);
 }
 }
 
 
 sei(); //unblock interrupts
 }
 return 0;
 }
=DeaD= писал(а):Нет, нет и еще раз нетмы можем продавать изделие как пообещали за 1700р. А можем не заморачиваться с поиском правильных подрядчиков, переговорами, выбором поставщиков материала и компонент и продавать набор за 3000р с маржой 5%
При любых расчетах в экономике подразумевается, что целью хозяйствующего субъекта является максимизация извлечения прибыли. И чтобы у вас был покупатель, вы будете вынуждены искать пути снижения себестоимости. Иначе покупатель предпочтет конкурентный товар (в данном случае самостоятельное изготовление). Но это все конечно чисто теоретически.
=DeaD= писал(а):А гадать есть что, у нас с ними разная входящая себестоимость была на один и тот же товар. Но цены по которым мы отпускали товар в свой магазин и к ним были одинаковые
Фишка в том, что они неправильно управляли запасами и товар у них лежал по 3 месяца. А цены на компьютерную технику имеют свойство снижаться достаточно быстро.
Это же я и говорил про входящую себестоимость, только другими словами. Себестоимость товара при прочих равных условиях определяется обычно 2 факторами: объемами закупок и каналом поставки. А затраты на управление запасами уже определяют размер коммерческих расходов. На рынке робототехники пока вроде нет признаков "рынка компьютеров". Предлагаю свернуть тему ценообразования, потому что мы уже от основной мысли ушли.
=DeaD= писал(а):Комплект механики без серв для шестинога на базе HXT900.
А когда ожидать на базе стандартных серв?







