#include "remote.h" #include "krabipacket.h" #include "strategieV2.h" #include "leds.h" #include "brasLateraux.h" #include "odometrie.h" #include "asservissement.h" #include #include #include GenericBuffer Remote::bufferRecv = GenericBuffer(); GenericBuffer Remote::bufferSend = GenericBuffer(); GenericBuffer::GenericBuffer() { size = 0; for(size_t i=0;iaddData(d); } if(USART_GetFlagStatus(REMOTE_USART_INDEX, USART_FLAG_TXE) != RESET) //Interuption type: 'TX register Empty' (i.e. ready to send) { if(!Remote::bufferSend.isEmpty()) // There IS some data to send USART_SendData(REMOTE_USART_INDEX, Remote::bufferSend.pop_front()); // We can only send one byte per TXE interrupt else // We ran out of data to send USART_ITConfig(REMOTE_USART_INDEX, USART_IT_TXE, DISABLE); // Disable the TXE interrupt } } } void Remote::addData(int data) { if (!mRemoteMod) return; USART_ITConfig(REMOTE_USART_INDEX, USART_IT_TXE, ENABLE); // Enable the TXE interrupt Remote::bufferSend.append(data); } void Remote::send(KrabiPacket &packet) { uint8_t size = packet.length(); uint8_t* data = packet.data(); for(uint8_t i = 0; isend(text); } void Remote::log(const char* format, ...) { char text[32]; va_list argptr; va_start(argptr, format); vsprintf(text, format, argptr); va_end(argptr); KrabiPacket packet(KrabiPacket::LOG_NORMAL); packet.addString(text); send(packet); } void Remote::debug(const char* format, ...) { char text[32]; va_list argptr; va_start(argptr, format); vsprintf(text, format, argptr); va_end(argptr); KrabiPacket packet(KrabiPacket::LOG_DEBUG); packet.addString(text); send(packet); } bool Remote::dataAvailable() { #ifdef ROBOTHW return REMOTE_USART_INDEX->SR & USART_FLAG_RXNE; #else return false; #endif } int Remote::receiveData() { #ifdef ROBOTHW while (!(REMOTE_USART_INDEX->SR & USART_FLAG_RXNE)); return ((int)(REMOTE_USART_INDEX->DR & 0x1FF)); #else return 0; #endif } void Remote::waitForConnection() { while(Remote::bufferRecv.isEmpty()); update(); for(int i(0); i<20; ++i) debug("."); } void Remote::update(bool allowChangeMode) { static long tick = 0; tick++; for(int i(0); i < KrabiPacket::MAX_WATCHES; i++) if (mWatchesEnabled[i]) { if ((KrabiPacket::W_TABLE)i == KrabiPacket::W_POSITION) { if (tick % 20 == i) sendWatch((KrabiPacket::W_TABLE)i); } else if (tick % 10 == i) sendWatch((KrabiPacket::W_TABLE)i); } /*static int test = 0; test++; if (test % 20 == 0) log("test pika");*/ if (bufferRecv.size > 2) { mRemoteMod = true; static int aa = 0; /*aa++; if (aa % 100 == 0)*/ //log("R %d %d %d", buffer.size, buffer.buf[buffer.size - 2], buffer.buf[buffer.size - 1]); for(int i(0); i < bufferRecv.size - 1; ++i) if (bufferRecv.buf[i] == 0x0D && bufferRecv.buf[i + 1]== 0x0A) { //log("R %d %d %d", buffer.size, buffer.buf[buffer.size - 2], buffer.buf[buffer.size - 1]); KrabiPacket p(bufferRecv.buf, i); if (i < bufferRecv.size - 2) memmove(bufferRecv.buf, bufferRecv.buf + i + 2, bufferRecv.size - (i + 2)); bufferRecv.size -= i + 2; i = 0; if (p.isValid()) treat(p); } } /*static int test = 0; test++; if (test % 100 == 0) { test = 0; Remote::getSingleton()->watch(KrabiPacket::W_POSITION, 10.f, 20.f, (float)ang); }*/ /*if (systick_count%10 == 0) { PositionPlusAngle p = Odometrie::odometrie->getPos(); Remote::getSingleton()->sendWatch(KrabiPacket::W_POSITION, p.position.x, p.position.y, p.angle); } if (systick_count%10 == 2) { Remote::getSingleton()->sendWatch(KrabiPacket::W_SPEED, Odometrie::odometrie->getVitesseLineaire(), Odometrie::odometrie->getVitesseAngulaire()); } if (systick_count%10 == 4) { Remote::getSingleton()->sendWatch(KrabiPacket::W_SPEED_TARGET, Asservissement::asservissement->getLinearSpeed(), Asservissement::asservissement->getAngularSpeed()); }*/ if (tick % 200 == 5) { KrabiPacket p(KrabiPacket::TIME_SYNC); p.add((uint16_t)StrategieV2::getTimeSpent()); Remote::getSingleton()->send(p); } /*if (!allowChangeMode && remoteMode && dataAvailable()) { int order = receiveData(); Remote::log("Got:"); Remote::getSingleton()->sendData(order); // Linear Speed if (order>=0 and order<=50) linSpeed = ((float)(order-25)) / 25. * LINEAR_REMOTE_SPEED_LIMIT; // Angular Speed if (order>=51 and order<=101) angSpeed = -((float)(order-75)) / 25. * ANGULAR_REMOTE_SPEED_LIMIT; }*/ } void Remote::treat(KrabiPacket &packet) { switch(packet.id()) { case KrabiPacket::REMOTE_MOD_SET: mRemoteMod = true; break; case KrabiPacket::REMOTE_MOD_RESET: mRemoteMod = false; break; case KrabiPacket::REMOTE_CONTROL_SET: mRemoteMod = true; mRemoteControl = true; break; case KrabiPacket::REMOTE_CONTROL_RESET: mRemoteControl = false; break; case KrabiPacket::SET_ODOMETRIE: { float wheelsize = packet.get(); float interaxis = packet.get(); Odometrie::odometrie->setSettings(interaxis, wheelsize); break; } case KrabiPacket::SET_PID_LIN: { float p = packet.get(); float i = packet.get(); float d = packet.get(); bool enabled = packet.get(); Asservissement::asservissement->getPIDDistance().setSettings(p, i, d); Asservissement::asservissement->setEnabledPIDDistance(enabled); break; } case KrabiPacket::SET_PID_ANG: { float p = packet.get(); float i = packet.get(); float d = packet.get(); bool enabled = packet.get(); Asservissement::asservissement->getPIDAngle().setSettings(p, i, d); Asservissement::asservissement->setEnabledPIDAngle(enabled); break; } case KrabiPacket::RUN_PID_TEST: { StrategieV2::resetTime(); float lin = packet.get(); float ang = packet.get(); float limit = packet.get(); uint16_t duration = packet.get(); Asservissement::asservissement->runTest(duration, lin, ang, limit); break; } case KrabiPacket::RUN_GOTO: { float x = packet.get(); float y = packet.get(); float speed = packet.get(); /*if (speed > 0) StrategieV2::setCurrentGoal(Position(x, y)); else StrategieV2::setCurrentGoal(Position(x, y));*/ Asservissement::asservissement->resume(); StrategieV2::addTemporaryAction(new ActionGoTo(Position(x, y)), true); break; } case KrabiPacket::STOP: { Asservissement::asservissement->stop(); break; } case KrabiPacket::WATCH_REQUIRE_ONCE: { uint16_t w = packet.get(); sendWatch((KrabiPacket::W_TABLE)w); break; } case KrabiPacket::WATCH_SET: { uint16_t w = packet.get(); mWatchesEnabled[w] = true; break; } case KrabiPacket::WATCH_RESET: { uint16_t w = packet.get(); mWatchesEnabled[w] = false; break; } case KrabiPacket::WATCH_DESELECT_ALL: { for(int i(0); i < KrabiPacket::MAX_WATCHES; i++) mWatchesEnabled[i] = false; break; } case KrabiPacket::TIME_RESET: StrategieV2::resetTime(); break; } } void Remote::sendWatch(KrabiPacket::W_TABLE w, int time) { KrabiPacket p(time == -1 ? KrabiPacket::WATCH_VARIABLE : KrabiPacket::WATCH_VARIABLE_TIMED, w); if (time >= 0) p.add((uint32_t) time); switch(w) { case KrabiPacket::W_WATCHES: { for(int i(1); i < KrabiPacket::MAX_WATCHES; i++) { p.add((uint8_t) i); p.add(mWatchesEnabled[i]); } break; } case KrabiPacket::W_POSITION: { PositionPlusAngle pos = Odometrie::odometrie->getPos(); p.add(pos.position.x); p.add(pos.position.y); p.add(pos.angle); break; } case KrabiPacket::W_SPEED: { p.add(Odometrie::odometrie->getVitesseLineaire()); p.add(Odometrie::odometrie->getVitesseAngulaire()); break; } case KrabiPacket::W_SPEED_TARGET: { p.add(Asservissement::asservissement->getLinearSpeed()); p.add(Asservissement::asservissement->getAngularSpeed()); break; } case KrabiPacket::W_ODOMETRIE: { p.add(Odometrie::odometrie->getWheelSize()); p.add(Odometrie::odometrie->getInterAxisDistance()); break; } case KrabiPacket::W_PID_LIN: { p.add(Asservissement::asservissement->getPIDDistance().getKp()); p.add(Asservissement::asservissement->getPIDDistance().getKi()); p.add(Asservissement::asservissement->getPIDDistance().getKd()); break; } case KrabiPacket::W_PID_ANG: { p.add(Asservissement::asservissement->getPIDAngle().getKp()); p.add(Asservissement::asservissement->getPIDAngle().getKi()); p.add(Asservissement::asservissement->getPIDAngle().getKd()); break; } case KrabiPacket::W_SHARPS: { for(int i(4); i < 8/*SharpSensor::END_SHARP_NAME*/; i++) { Sensor::OutputSensor out = StrategieV2::getSensors()[i]->getValue(); p.add((uint16_t) out.f); p.add(out.b); } break; } default: return; } send(p); } bool Remote::isInRemoteMod() { return mRemoteMod; } bool Remote::isInRemoteControl() { return mRemoteControl; } float Remote::getLeftPWM() { return linSpeed; #if defined(STM32F40_41xxx) || defined(STM32F10X_MD) return linSpeed + angSpeed; #else return linSpeed - angSpeed; #endif } float Remote::getRightPWM() { return angSpeed; #if defined(STM32F40_41xxx) || defined(STM32F10X_MD) return linSpeed - angSpeed; #else return linSpeed + angSpeed; #endif }