I'm new in Omnet Veins. I try to create my own application. So first of all, I have done this in the existing TraciDemo11p files (I have just kept the files name and modify the code).
In the first step, I want to make all nodes sending a HelloMsg (a new packet that I have created .msg .h and .cc).
To well understand how messages are exchanged between nodes, I launched the simulation and all is well, but I cannot realize if the messages are received by nodes or not.
This is a screenshot of what I have:
enter image description here
I followed the transmission of the message between the application, mac and phy layers. I can see that the message is successfully transmitted by node1 for example. But does the message on node[0] "packet was not detected by the card. power was under sensitivity threshold" mean that the packet was not received by node[0]?. If it is the case, how can I fix that? Also, I cannot find the source file of this message (apparently, in PhyLayer80211p.cc or BasehyLayer.cc but I cannot find it).
In the second step, I want to use two RSUs. Nodes broadcast a helloMessage and then each RSU will repeat the received signal. To clarify more, this exactly what I have:
First of all. I add another RSU to the veins example as follows:
##########################################################
# RSU SETTINGS #
# #
# #
##########################################################
*.rsu[0].mobility.x = 6490
*.rsu[0].mobility.y = 1000
*.rsu[0].mobility.z = 3
*.rsu[1].mobility.x = 7491
*.rsu[1].mobility.y = 1000
*.rsu[1].mobility.z = 3
*.rsu[*].applType = "TraCIDemoRSU11p"
*.rsu[*].appl.headerLength = 80 bit
*.rsu[*].appl.sendBeacons = false
*.rsu[*].appl.dataOnSch = false
*.rsu[*].appl.beaconInterval = 1s
*.rsu[*].appl.beaconUserPriority = 7
*.rsu[*].appl.dataUserPriority = 5
Also, I made two maxInterferenceDistance, one of the nodes and the other for the RSUs:
##########################################################
# 11p specific parameters #
# #
# NIC-Settings #
##########################################################
*.connectionManager.sendDirect = true
*.connectionManager.maxInterfDist = 1000m #2600m
*.connectionManager.drawMaxIntfDist = false #false
*.connectionManager.maxInterfDistNodes = 300m
*.connectionManager.drawMaxIntfDistNodes = false
*.**.nic.mac1609_4.useServiceChannel = false
*.**.nic.mac1609_4.txPower = 20mW
*.**.nic.mac1609_4.bitrate = 6Mbps
*.**.nic.phy80211p.sensitivity = -89dBm
*.**.nic.phy80211p.useThermalNoise = true
*.**.nic.phy80211p.thermalNoise = -110dBm
*.**.nic.phy80211p.decider = xmldoc("config.xml")
*.**.nic.phy80211p.analogueModels = xmldoc("config.xml")
*.**.nic.phy80211p.usePropagationDelay = true
*.**.nic.phy80211p.antenna = xmldoc("antenna.xml", "/root/Antenna[#id='monopole']")
To make the transmission range of RSU different on that of nodes, I made this change in the isInRange function of the baseConnectionMannager:
bool BaseConnectionManager::isInRange(BaseConnectionManager::NicEntries::mapped_type pFromNic, BaseConnectionManager::NicEntries::mapped_type pToNic)
{
double dDistance = 0.0;
if ((pFromNic->hostId == 7) || (pFromNic->hostId == 8)) {
EV<<"RSU In range from: "<<pFromNic->getName()<<" "<<pFromNic->hostId<<" to: "<<pToNic->getName()<<" "<<pToNic->hostId<<"\n";
if(useTorus) {
dDistance = sqrTorusDist(pFromNic->pos, pToNic->pos, *playgroundSize);
} else {
dDistance = pFromNic->pos.sqrdist(pToNic->pos);
}
return (dDistance <= maxDistSquared);
} else {
if(useTorus) {
dDistance = sqrTorusDist(pFromNic->pos, pToNic->pos, *playgroundSize);
} else {
dDistance = pFromNic->pos.sqrdist(pToNic->pos);
}
return (dDistance <= maxDistSquaredNodes);
}
}
Where node IDs 7 and 8 are the RSUs in the scenario I run.
In addition, I have the TraciDemo11p (for nodes) and TraciDemoRSU11p (for RSUs) modified as follow:
- In the TraciDemo11p, nodes when enter the network broadcast a Hello message to all their neighbors. The code is:
void TraCIDemo11p::initialize(int stage) {
BaseWaveApplLayer::initialize(stage);
if (stage == 0) {
HelloMsg *msg = createMsg();
SendHello(msg);
}
}
HelloMsg* TraCIDemo11p::createMsg() {
int source_id = myId;
double t0 = 0;
int port = 0;
char msgName[20];
sprintf(msgName, "send Hello from %d at %f from gate %d",source_id, t0, port);
HelloMsg* msg = new HelloMsg(msgName);
populateWSM(msg);
return msg;
}
void TraCIDemo11p::SendHello(HelloMsg* msg) {
findHost()->getDisplayString().updateWith("r=16,green");
msg->setSource_id(myId);
cMessage* mm = dynamic_cast<cMessage*>(msg);
scheduleAt(simTime() + 10 + uniform(0.01, 0.02), mm);
}
void TraCIDemo11p::handleSelfMsg(cMessage* msg) {
if (dynamic_cast<HelloMsg*>(msg)) {
HelloMsg* recv = dynamic_cast<HelloMsg*>(msg);
ASSERT(recv);
int sender = recv->getSource_id();
if (sender == myId) {
EV <<myId <<" broadcasting Hello Message \n";
recv->setT0(SIMTIME_DBL(simTime()));
sendDown(recv->dup());
}
}
else {
BaseWaveApplLayer::handleSelfMsg(msg);
}
}
void TraCIDemo11p::onHelloMsg(HelloMsg* hmsg) {
if ((hmsg->getSource_id() == 7) || (hmsg->getSource_id() == 8)) {
EV <<"Node: "<<myId<<" receiving HelloMsg from rsu: "<<hmsg->getSource_id()<<"\n";
} else {
EV <<"Node: "<<myId<<" receiving HelloMsg "<<hmsg->getKind()<<" from node: "<<hmsg->getSource_id()<<"\n";
NBneighbors++;
neighbors.push_back(hmsg->getSource_id());
EV <<"Node: "<<myId<<" neighbors list: ";
list<int>::iterator it = neighbors.begin();
while (it != neighbors.end()) {
EV <<*it<<" ";
it++;
}
}
}
void TraCIDemo11p::handlePositionUpdate(cObject* obj) {
BaseWaveApplLayer::handlePositionUpdate(obj);
}
On the other hand, RSUs just repeat the message they received from nodes. So, I have on the TraciDemoRSU11p:
void TraCIDemoRSU11p::onHelloMsg(HelloMsg* hmsg) {
if ((hmsg->getSource_id() != 7) && (hmsg->getSource_id() != 8))
{
EV <<"RSU: "<<myId<<" receiving HelloMsg "<<hmsg->getKind()<<" from node: "<<hmsg->getSource_id()<<" at: "<<SIMTIME_DBL(simTime())<<" \n";
//HelloMsg *msg = createMsg();
//SendHello(msg);
hmsg->setSenderAddress(myId);
hmsg->setSource_id(myId);
sendDelayedDown(hmsg->dup(), 2 + uniform(0.01,0.2));
}
else {
EV<<"Successful connection between RSUs \n";
EV <<"RSU: "<<myId<<" receiving HelloMsg "<<hmsg->getKind()<<" from node: "<<hmsg->getSource_id()<<"\n";
}
}
After the execution of this code, I can see:
a few numbers of vehicles receiving the hello message from their neighbors.
also, just a few messages were received by the two RSUs.
Each RSUs repeats the signal it receives, but there is no communication between the two RSU, which are supposed in the transmission of one another.
And always I have a lot of this message "packet was not detected by the card. power was under sensitivity threshold" printed on my screen.
Is there any problem in the transmission range or it is a question of interference? Also, I would like to mention that in the analysis there is no packet loss.
Thanks in advance.
Please help.
Related
I am currently working on creating a network of multisensors (measuring temp, humidity ect). There will be tens or in some buildings even hundreds of sensors measuring at the same time. All these sensors send their data via a http GET request to a local esp32 server that processes the data and converts it into whatever the building's contol system can work with (KNX, BACnet, MODbus). Now I stress tested this server and found out that it can process around 1400 requests per minute before the sender gets no response anymore. This seems like a high amount but if a sensor sends its data every 2 seconds it means there will be a limit of around 45 sensors. I need to find a way how to process such a request quicker, this is the code I currently use:
server.on("/get-data", HTTP_GET, [](AsyncWebServerRequest *request)
{handle_get_data(request); request->send(200); });
void handle_get_data(AsyncWebServerRequest *request)
{
packetval++;
sensorData.humidity = request->arg("humidity").toFloat();
sensorData.temperature = request->arg("temperature").toFloat();
sensorData.isMovement = request->arg("isMovement");
sensorData.isSound = request->arg("isSound");
sensorData.luxValue = request->arg("luxValue").toDouble();
sensorData.RSSI = request->arg("signalValue").toInt();
sensorData.deviceID = request->arg("deviceID");
sensorData.btList = request->arg("btList");
if (deviceList.indexOf(sensorData.deviceID) == -1)
{
deviceList += sensorData.deviceID;
activeSensors++;
}
if (sensorData.isMovement || sensorData.isSound)
{
sendDataFlag = true;
}
}
I use the AsyncTCP library.
Now I measured the execution time of the function handle_get_data() and it turns out it is only ~175uS which is very quick. However the time between two calls of handle_get_data() is around 6ms which is really slow but it still doesnt explain why I can only process 1400 per minute or 24 per second (6ms = 155Hz why is my limit 24Hz?). Other than that I do not use any other code during the processing of a request, is it perhaps a limitation in the library? Is there another way to process such a request?
A request looks like this: http://192.168.6.51:80/get-data?humidity=32.0&temperature=32.0&isMovement=1&isSound=1&luxValue=123&RSSI=32&deviceID=XX:XX:XX:XX:XX:XX&btList=d1d2d3d4d5d6d7
If there is really nothing I can do I can always switch to a raspberry pi to process everything but I would rather stick to esp32 since I want to easily create an own PCB.
Thanks for all the help!
Creating a websocket instead of using http requests solved the issue for me:
AsyncWebSocket ws("/ws");
void setup()
{
ws.onEvent(onWsEvent);
server.addHandler(&ws);
}
AsyncWebSocketClient *wsClient;
void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len)
{
if (type == WS_EVT_DATA)
{
AwsFrameInfo *info = (AwsFrameInfo *)arg;
String msg = "";
packetval++;
if (info->final && info->index == 0 && info->len == len)
{
if (info->opcode == WS_TEXT)
{
for (size_t i = 0; i < info->len; i++)
{
msg += (char)data[i];
}
}
}
sensorData.humidity = msg.substring(msg.indexOf("<hum>") + 5, msg.indexOf("</hum>")).toFloat();
sensorData.temperature = msg.substring(msg.indexOf("<tem>") + 5, msg.indexOf("</tem>")).toFloat();
sensorData.isMovement = (msg.substring(msg.indexOf("<isMov>") + 7, msg.indexOf("</isMov>")) == "1");
sensorData.isSound = (msg.substring(msg.indexOf("<isSnd>") + 7, msg.indexOf("</isSnd>")) == "1");
sensorData.luxValue = msg.substring(msg.indexOf("<lux>") + 5, msg.indexOf("</lux>")).toDouble();
sensorData.RSSI = msg.substring(msg.indexOf("<RSSI>") + 6, msg.indexOf("</RSSI>")).toInt();
sensorData.deviceID = msg.substring(msg.indexOf("<dID>") + 5, msg.indexOf("</dID>"));
sensorData.btList = msg.substring(msg.indexOf("<bt>") + 4, msg.indexOf("</bt>"));
if (deviceList.indexOf(sensorData.deviceID) == -1)
{
deviceList += sensorData.deviceID;
activeSensors++;
}
if (sensorData.isMovement || sensorData.isSound)
{
sendDataFlag = true;
}
}
}
This will process more than 11000 packets per minute (200kb/s). The execution time of void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) takes ~500uS now which means there is definitly optimising to do in this function but the time between two calls is reduced all the way to 1ms.
I tried to cast two messages in the onWSM function, one of the message is the accident message from TraCIDemo11p example see link; https://github.com/sommer/veins/blob/master/src/veins/modules/application/traci/TraCIDemo11p.cc and the other message I created myself.Simulation stops when handling of the accident message begins.
void MyClusterApp::onWSM(BaseFrame1609_4* frame)
{
// Your application has received a data message from another car or RSU
// code for handling the message goes here, see TraciDemo11p.cc for examples
joinMessage* wsm = check_and_cast<joinMessage*>(frame);
if (currentSubscribedServiceId == 7)
{
if(wsm->getRecipientAddress() == myId)
{
mClusterMembers.insert(wsm->getSenderId());
}
}
}
void MyClusterApp::onWSM_B(BaseFrame1609_4* frame)
{
accident* wsm = check_and_cast<accident*>(frame);
if (currentSubscribedServiceId == 8)
{
findHost()->getDisplayString().setTagArg("i", 1, "green");
if (mobility->getRoadId()[0] != ':') traciVehicle->changeRoute(wsm->getDemoData(), 9999);
if (!sentMessage) {
sentMessage = true;
wsm->setSenderAddress(myId);
wsm->setSerial(3);
for( NodeIdSetIterator it = mClusterMembers.begin(); it != mClusterMembers.end(); it++)
{
wsm->setRecipientAddress((*it));
scheduleAt(simTime() + 2 + uniform(0.01, 0.2), wsm->dup());
}
}
}
}
A runtime error occurred:
check_and_cast(): Cannot cast (veins::accident*) to type 'veins::joinMessage *' -- in module (veins::MyClusterApp) VANETScenario.node[1].appl (id=15), at t=74.797089255834s, event #711255
Launch a debugger with the following command?
nemiver --attach=4377 &
It seems that MyClusterApp::onWSM() may handle various types of messages. Therefore, I suggest use dynamic_cast to recognize the type of message - it is safe and returns nullptr when a message cannot be cast.
An example of modification:
void MyClusterApp::onWSM(BaseFrame1609_4* frame) {
joinMessage* wsm = dynamic_cast<joinMessage*>(frame);
if (wsm) {
if (currentSubscribedServiceId == 7) {
if(wsm->getRecipientAddress() == myId) {
mClusterMembers.insert(wsm->getSenderId());
}
}
} else {
// frame is not a pointer to joinMessage
}
}
I am using IXGBE Nic, using dpdk 19.11 multi rx queue with rss "ETH_RSS_TCP | ETH_RSS_IP".
IXGBE support max 64 queues, and i used 4 queues. But all packages arrvied to the same queue(queue 0), it seems rss function not work well.
The following is the pseudo code of my rss part. Is the rss function not taking effect due to my incorrect configuration?
static int rss_setup(const int port_id, const uint16_t nb_queues)
{
int i;
int ret;
struct rte_eth_dev_info dev_info;
struct rte_eth_rss_reta_entry64 *reta_conf = NULL;
rte_eth_dev_info_get(port_id, &dev_info);
if (nb_queues == 0) {
return ERR_VAL;
}
reta_conf = calloc(dev_info.reta_size / RTE_RETA_GROUP_SIZE,
sizeof(struct rte_eth_rss_reta_entry64));
if (!reta_conf) {
return ERR_MEM;
}
for (i = 0; i < dev_info.reta_size; i++) {
struct rte_eth_rss_reta_entry64 *one_reta_conf =
&reta_conf[i / RTE_RETA_GROUP_SIZE];
one_reta_conf->reta[i % RTE_RETA_GROUP_SIZE] = i % nb_queues;
}
for (i = 0; i < dev_info.reta_size / RTE_RETA_GROUP_SIZE; i++) {
struct rte_eth_rss_reta_entry64 *one_reta_conf = &reta_conf[i];
one_reta_conf->mask = 0xFFFFFFFFFFFFFFFFULL;
}
ret = rte_eth_dev_rss_reta_update(port_id, reta_conf, dev_info.reta_size);
if (ret < 0) {
printf("cannot update rss reta at port %d: %s\n",
port_id, rte_strerror(-ret));
}
free(reta_conf);
return ERR_OK;
}
main (){
struct rte_eth_conf conf = {0};
conf.link_speeds = ETH_LINK_SPEED_AUTONEG;
conf.txmode.mq_mode = ETH_MQ_TX_NONE;
conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
struct rte_eth_dev_info dev_info;
rte_eth_dev_info_get(port_id, &dev_info);
int rss_enable = 0;
uint64_t def_rss_hf = ETH_RSS_TCP | ETH_RSS_IP;
struct rte_eth_rss_conf rss_conf = {
NULL,
40,
def_rss_hf,
};
rss_conf.rss_hf &= dev_info->flow_type_rss_offloads;
if (rss_conf.rss_hf) {
rss_enable = 1;
conf->rx_adv_conf.rss_conf = rss_conf;
conf->rxmode.mq_mode = ETH_MQ_RX_RSS;
rss_setup(port_id, 4); // queues cnt is 4
}
}
Looks like the program does not invoke rte_eth_dev_configure() before invoking rss_setup(). This is not correct as rte_eth_dev_configure() "must be invoked first before any other function in the Ethernet API" (doc reference). Please re-arrange the program to first invoke rte_eth_dev_configure() with rx_adv_conf.rss_conf and ETH_MQ_RX_RSS specified, then proceed with the rest of bring-up.
In rss_setup(), the program invokes rte_eth_dev_rss_reta_update(). For the PMD in question, this API can only be invoked in started state (code reference). So please re-arrange the program a bit more to invoke rte_eth_dev_start() before rss_setup().
Please make sure that TCP source port numbers (and/or IP source addresses) are randomised at the sender side. If IP/TCP source and destination fields do not vary, it's no surprise that the packets end up in the same Rx queue.
I am writing some software to control a quadcopter and have got completely stuck with RtosTimers. I am getting the error "Error: No instance of constructor "rtos::RtosTimer::RtosTimer" matches the argument list in "flightController.h", Line: 13, Col: 29"
I have looked at the example code in the handbook and my code seems to match. I have also googled but I couldn't find anything on using RtosTimers inside of RtosThreads.
Maybe I am going about this the wrong way so if anyone has any suggestions it would be much appreciated.
Here is the code that is causing me problems
//Rtos Timers
RtosTimer UpdateFlightTimer(Task500Hz, osTimerPeriodic, (void *)0);
RtosTimer UpdateCommandTimer(Task50Hz, osTimerPeriodic, (void *)0);
// A thread to monitor the serial ports
void FlightControllerThread(void const *args)
{
UpdateFlightTimer.start(2);
UpdateCommandTimer.start(20);
// Wait here forever
Thread::wait(osWaitForever);
}
void Task500Hz(void const *n)
{
//Get IMU data and convert to yaw, pitch, roll
_freeIMU.getQ(_rawQuaternion);
_freeIMU.getRate(_gyroRate);
GetAttitude();
//Rate mode
if(_rate == true && _stab == false)
{
//Update rate PID process value with gyro rate
_yawRatePIDController->setProcessValue(_gyroRate[0]);
_pitchRatePIDController->setProcessValue(_gyroRate[2]);
_rollRatePIDController->setProcessValue(_gyroRate[1]);
//Update rate PID set point with desired rate from RC
_yawRatePIDController->setSetPoint(_rcConstrainedCommands[0]);
_pitchRatePIDController->setSetPoint(_rcConstrainedCommands[1]);
_rollRatePIDController->setSetPoint(_rcConstrainedCommands[2]);
//Compute rate PID outputs
_ratePIDControllerOutputs[0] = _yawRatePIDController->compute();
_ratePIDControllerOutputs[1] = _pitchRatePIDController->compute();
_ratePIDControllerOutputs[2] = _rollRatePIDController->compute();
}
//Stability mode
else
{
//Update stab PID process value with ypr
_yawStabPIDController->setProcessValue(_yrp[0]);
_pitchStabPIDController->setProcessValue(_yrp[2]);
_rollStabPIDController->setProcessValue(_yrp[1]);
//Update stab PID set point with desired angle from RC
_yawStabPIDController->setSetPoint(_yawTarget);
_pitchStabPIDController->setSetPoint(_rcConstrainedCommands[1]);
_rollStabPIDController->setSetPoint(_rcConstrainedCommands[2]);
//Compute stab PID outputs
_stabPIDControllerOutputs[0] = _yawStabPIDController->compute();
_stabPIDControllerOutputs[1] = _pitchStabPIDController->compute();
_stabPIDControllerOutputs[2] = _rollStabPIDController->compute();
//if pilot commanding yaw
if(abs(_rcConstrainedCommands[0]) > 5)
{
_stabPIDControllerOutputs[0] = _rcConstrainedCommands[0]; //Feed to rate PID (overwriting stab PID output)
_yawTarget = _yrp[0];
}
//Update rate PID process value with gyro rate
_yawRatePIDController->setProcessValue(_gyroRate[0]);
_pitchRatePIDController->setProcessValue(_gyroRate[2]);
_rollRatePIDController->setProcessValue(_gyroRate[1]);
//Update rate PID set point with desired rate from stab PID
_yawRatePIDController->setSetPoint(_stabPIDControllerOutputs[0]);
_pitchRatePIDController->setSetPoint(_stabPIDControllerOutputs[1]);
_rollRatePIDController->setSetPoint(_stabPIDControllerOutputs[2]);
//Compute rate PID outputs
_ratePIDControllerOutputs[0] = _yawRatePIDController->compute();
_ratePIDControllerOutputs[1] = _pitchRatePIDController->compute();
_ratePIDControllerOutputs[2] = _rollRatePIDController->compute();
}
//Calculate motor power if flying
if(_rcCommands[3] > 0 && _armed == true)
{
_motorPower[0] = Constrain(_rcConstrainedCommands[3] + _ratePIDControllerOutputs[1] + _ratePIDControllerOutputs[2] + _ratePIDControllerOutputs[0], MOTORS_MIN, MOTORS_MAX);
_motorPower[1] = Constrain(_rcConstrainedCommands[3] + _ratePIDControllerOutputs[1] - _ratePIDControllerOutputs[2] - _ratePIDControllerOutputs[0], MOTORS_MIN, MOTORS_MAX);
_motorPower[2] = Constrain(_rcConstrainedCommands[3] - _ratePIDControllerOutputs[1] - _ratePIDControllerOutputs[2] + _ratePIDControllerOutputs[0], MOTORS_MIN, MOTORS_MAX);
_motorPower[3] = Constrain(_rcConstrainedCommands[3] - _ratePIDControllerOutputs[1] + _ratePIDControllerOutputs[2] - _ratePIDControllerOutputs[0], MOTORS_MIN, MOTORS_MAX);
}
//Not flying
else
{
//Disable motors
_motorPower[0] = MOTORS_OFF;
_motorPower[1] = MOTORS_OFF;
_motorPower[2] = MOTORS_OFF;
_motorPower[3] = MOTORS_OFF;
_notFlying ++;
if(_notFlying > 200) //Not flying for 1 second
{
//Reset iteratior
_notFlying = 0;
//Zero gyro
_freeIMU.zeroGyro();
//Reset I
_yawRatePIDController->reset();
_pitchRatePIDController->reset();
_rollRatePIDController->reset();
_yawStabPIDController->reset();
_pitchStabPIDController->reset();
_rollStabPIDController->reset();
}
}
//Set motor power
_motor1.write(_motorPower[0]);
_motor2.write(_motorPower[1]);
_motor3.write(_motorPower[2]);
_motor4.write(_motorPower[3]);
}
void Task50Hz(void const *n)
{
//Get RC control values
//Constrain
//Rate mode
if(_rate == true && _stab == false)
{
_rcConstrainedCommands[0] = Constrain(_rcCommands[0], RC_YAW_RATE_MIN, RC_YAW_RATE_MAX);
_rcConstrainedCommands[1] = Constrain(_rcCommands[1], RC_PITCH_RATE_MIN, RC_PITCH_RATE_MAX);
_rcConstrainedCommands[2] = Constrain(_rcCommands[2], RC_ROLL_RATE_MIN, RC_ROLL_RATE_MAX);
_rcConstrainedCommands[3] = Constrain(_rcCommands[3], RC_THRUST_MIN, RC_THRUST_MAX);
}
else
{
_rcConstrainedCommands[0] = Constrain(_rcCommands[0], RC_YAW_RATE_MIN, RC_YAW_RATE_MAX);
_rcConstrainedCommands[1] = Constrain(_rcCommands[1], RC_PITCH_ANGLE_MIN, RC_PITCH_ANGLE_MAX);
_rcConstrainedCommands[2] = Constrain(_rcCommands[2], RC_ROLL_ANGLE_MIN, RC_ROLL_ANGLE_MAX);
_rcConstrainedCommands[3] = Constrain(_rcCommands[3], RC_THRUST_MIN, RC_THRUST_MAX);
}
}
My program can be found at http://mbed.org/users/joe4465/code/QuadMK5/
And the problem is in flightController.h I think it should be clear what I am trying to do but if anyone isn't sure let me know.
I also have another totally unrelated problem. I can set my PID variables over serial and then save them to a config file but 1 in 3 times if will hang just after it has saved the data to the file and I'm not sure why. Does anyone have any idea what could cause this?
Thanks Joe
I forgot to put void const *n in the parameters of the functions where they are defined at the top
We have developed a multiplayer game using google play services.
When we send a request to the api for inviting friends to play, on clicking auto pick, the opponent's name does not show, instead the list shows any random name as in Player_1231,Player_3333 etc.
We need help regarding this issue. We need proper player names to play the game.Kindly check the screenshots attached.
Immediate help will be appreciated.
Please find the code below:
public void onRoomConnected(int statusCode, Room room) {
// TODO Auto-generated method stub
if (statusCode != mGamesClient.STATUS_PARTICIPANT_NOT_CONNECTED) {
// Toast.makeText(this, " is PARTICIPANT_CONNECTED.",
// Toast.LENGTH_SHORT).show();
roomId = room.getRoomId();
room_creator_id = room.getCreatorId();
// participantId = p.getParticipantId();
current_player_id = room.getParticipantId(mGamesClient
.getCurrentPlayerId());
Asset.self = Asset.username;
if (room_creator_id != null) {
if (room_creator_id.equals(current_player_id)) {
Server = true;
}
}
// Toast.makeText(this,
// " is PARTICIPANT_CONNECTED."+room_creator_id,
// Toast.LENGTH_SHORT).show();
par = null;
par = room.getParticipants();
for (Participant p : par) {
if (!p.getParticipantId().equals(current_player_id)) {
System.out.println(current_player_id
+ " After 1 connect " + p.getParticipantId());
participantId = p.getParticipantId();
Asset.opponent = p.getDisplayName();
break;
}
}
menu.initPage(GameConst.SELECTLEVEL_PAGE_ONLINE);
menu.Start_Selection_Timer();
}
// Toast.makeText(this, " is onRoomConnected.",
// Toast.LENGTH_SHORT).show();
}
PLAY ONLINE---------------
public void startQuickGame() {
// automatch criteria to invite 1 random automatch opponent.
// You can also specify more opponents (up to 3).
if (mGamesClient.isConnected()) {
Bundle am = RoomConfig.createAutoMatchCriteria(1, 1, 0);
// build the room config:
RoomConfig.Builder roomConfigBuilder = makeBasicRoomConfigBuilder();
roomConfigBuilder.setAutoMatchCriteria(am);
RoomConfig roomConfig = roomConfigBuilder.build();
// create room:
mGamesClient.createRoom(roomConfig);
} else {
Toast.makeText(con, "Wait for connection or try after some time",
Toast.LENGTH_SHORT).show();
mGamesClient.connect();
}
// go to game screen
}