iCub-main
Loading...
Searching...
No Matches
boardTransceiver.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2014 iCub Facility, Istituto Italiano di Tecnologia
3 * Authors: Alberto Cardellino
4 * CopyPolicy: Released under the terms of the LGPLv2.1 or later, see LGPL.TXT
5 *
6 */
7
8
9// --------------------------------------------------------------------------------------------------------------------
10// - macros
11// --------------------------------------------------------------------------------------------------------------------
12
13
14
15// --------------------------------------------------------------------------------------------------------------------
16// - external dependencies
17// --------------------------------------------------------------------------------------------------------------------
18
19using namespace std;
20
21#include <stdint.h>
22#include <stdlib.h>
23#include <stdio.h>
24#include <string.h>
25
26#include "boardTransceiver.hpp"
27#include "FeatureInterface.h"
28
29#include "EOYtheSystem.h"
30#include "EoCommon.h"
31#include "EOnv.h"
32#include "EOnv_hid.h"
33#include "EOrop.h"
34#include "EoProtocol.h"
35
36
37#include "EOdeviceTransceiver.h"
38
39#include "EOprotocolConfigurator.h"
40
41#include "EoProtocol.h"
42#include "EoProtocolMN.h"
43#include "EoProtocolMC.h"
44#include "EoProtocolAS.h"
45#include "EoProtocolSK.h"
46
47
48
49#include <yarp/os/LogStream.h>
50
51#include <yarp/os/Time.h>
52#include <yarp/os/Bottle.h>
53
54using namespace yarp::os;
55
56
57EOnvSet* arrayofnvsets[16] = {NULL};
58
60{
61 yTrace();
62
63 UDP_socket = NULL;
64 remoteipport = 0;
65 localipaddr = 0;
66 remoteipaddr = 0;
67
68 protboardnumber = eo_prot_BRDdummy;
69 p_RxPkt = NULL;
70 devtxrx = NULL;
71 transceiver = NULL;
72 nvset = NULL;
73
74 pApplStatus = NULL;
75
76 oneNV = eo_nv_New();
77
78 memcpy(&devtxrxcfg, &eo_devicetransceiver_cfg_default, sizeof(eOdevicetransceiver_cfg_t));
79}
80
85
86bool BoardTransceiver::configure(yarp::os::ResourceFinder &rf)
87{
88 yDebug() << " input is " << rf.toString().c_str();
89
90 if(!rf.check("PC104IpAddress"))
91 {
92 yError() << "missing PC104IpAddress";
93 return false;
94 }
95
96 if(!rf.check("emsIpAddress"))
97 {
98 yError() << "missing emsIpAddress";
99 return false;
100 }
101
102 if(!rf.check("port"))
103 {
104 yError() << "missing port";
105 return false;
106 }
107
108 yDebug() << " I have all params I need!!";
109 Bottle parameter1( rf.find("PC104IpAddress").asString() );
110
111 int port = rf.find("port").asInt32(); // .get(1).asInt32();
112 strcpy(_fId.PC104ipAddr.string, parameter1.toString().c_str());
113 _fId.PC104ipAddr.port = port;
114
115 Bottle parameter2( rf.find("emsIpAddress").asString() ); // .findGroup("IpAddress");
116 strcpy(_fId.EMSipAddr.string, parameter2.toString().c_str());
117 _fId.EMSipAddr.port = port;
118
121
124
125 // Check input parameters
126 yDebug() << " boardTransceiver - referred to EMS: " << _fId.EMSipAddr.string;
127
128
129 ACE_UINT32 hostip = (_fId.PC104ipAddr.ip1 << 24) | (_fId.PC104ipAddr.ip2 << 16) | (_fId.PC104ipAddr.ip3 << 8) | (_fId.PC104ipAddr.ip4);
130 ACE_INET_Addr myIP((u_short)_fId.PC104ipAddr.port, hostip);
131// myIP.dump();
132
133 if(!createSocket(myIP) )
134 { return NULL; }
135
136 return true;
137}
138
139bool BoardTransceiver::createSocket(ACE_INET_Addr local_addr)
140{
141 yTrace();
142
143 UDP_socket = new ACE_SOCK_Dgram();
144 char tmp[64];
145
146 if(-1 == UDP_socket->open(local_addr))
147 {
148 local_addr.addr_to_string(tmp, 64);
149 yError() << "\n/---------------------------------------------------\\"
150 << "\n| Unable to bind to local IP address " << tmp
151 << "\n\\---------------------------------------------------/";
152 delete UDP_socket;
153 UDP_socket = NULL;
154 }
155 else
156 {
157 yTrace() << "BoardTransceiver created socket correctly!";
158 }
159
160 return true;
161}
162
163bool BoardTransceiver::init(yarp::os::Searchable &config, uint32_t _localipaddr, uint32_t _remoteipaddr, uint16_t _remoteipport, uint16_t _pktsizerx, FEAT_boardnumber_t _board_n)
164{
165 // the configuration of the transceiver: it is specific of a given remote board
166 yTrace();
167
168 // assign values of some member variables
169
171 localipaddr = _localipaddr;
172 remoteipaddr = _remoteipaddr;
173 remoteipport = _remoteipport;
174
175
176
177 if(!initProtocol(config))
178 {
179 yError() << "BoardTransceiver::initProtocol() fails";
180 return false;
181 }
182
183
184 if(!prepareTransceiverConfig(config))
185 {
186 yError() << "BoardTransceiver::prepareTransceiverConfig() fails";
187 return false;
188 }
189
190 // now devtxrxcfg is ready, thus ...
191 // initialise the transceiver: it creates a EOtransceiver and its EOnvSet
192 devtxrx = eo_devicetransceiver_New(&devtxrxcfg); // never returns NULL. it calls its error manager
193 if(devtxrx == NULL)
194 return false;
195
196 // retrieve the transceiver
197 transceiver = eo_devicetransceiver_GetTransceiver(devtxrx); //CHECK!!!!!
198 if(transceiver == NULL)
199 return false;
200
201 // retrieve the nvset
202 nvset = eo_devicetransceiver_GetNVset(devtxrx); //CHECK!!!!!
203 if(NULL == nvset)
204 {
205 return false;
206 }
207
209
210
211 // build the packet used for reception.
212 p_RxPkt = eo_packet_New(_pktsizerx);
213 if(p_RxPkt == NULL)
214 return false;
215
216 eOnvID32_t id32status = eoprot_ID_get(eoprot_endpoint_management, eoprot_entity_mn_appl, 0, eoprot_tag_mn_appl_status);
217 eo_nvset_NV_Get(nvset, eok_ipv4addr_localhost, id32status, oneNV);
218
219 pApplStatus = (eOmn_appl_status_t*) oneNV->ram;
220 pApplStatus->currstate = applstate_config;
221
222
223
224 return true;
225}
226
227
228void fromDouble(ACE_Time_Value &v, double x,int unit) {
229#ifdef YARP_HAS_ACE
230 v.msec(static_cast<int>(x*1000/unit+0.5));
231#else
232 v.tv_usec = static_cast<int>(x*1000000/unit+0.5) % 1000000;
233 v.tv_sec = static_cast<int>(x/unit);
234#endif
235}
236
237// Main loop here!!!
239{
240 ACE_INET_Addr sender_addr;
241 ssize_t recv_size;
242 ACE_Time_Value recvTimeOut;
243 fromDouble(recvTimeOut, 1.0);
244
245 uint8_t *p_sendData;
246 uint16_t bytes_to_send = 0;
247
248 uint8_t incoming_msg[RECV_BUFFER_SIZE];
249
250 bool parsepacket = false;
251 bool transmitpacket = false;
252
253 //std::cout << " BoardTransceiver is running happily!" << std::endl;
254
255 // get pkt from socket: blocking call with timeout
256 recv_size = UDP_socket->recv((void *) incoming_msg, RECV_BUFFER_SIZE, sender_addr, 0, &recvTimeOut);
257
258 switch(pApplStatus->currstate)
259 {
260 case applstate_config:
261 { // in configuration state the ems is triggered only for non-empty packets. it sends back a ropframe even if empty
262 if(recv_size > 0)
263 {
264 parsepacket = true;
265 transmitpacket = true;
266 }
267 } break;
268
269 case applstate_running:
270 { // in running state the ems is triggered every millisecond. it parses non-empty packets. it always sends a ropframe back, even if empty.
271 if(recv_size > 0)
272 {
273 parsepacket = true;
274 }
275 transmitpacket = true;
276 } break;
277
278 case applstate_error:
279 {
280 if(recv_size > 0)
281 {
282 parsepacket = true;
283 transmitpacket = true;
284 }
285 } break;
286
287 default:
288 {
289
290 } break;
291
292 }
293
294 if(parsepacket)
295 {
296 onMsgReception(incoming_msg, recv_size);
297 }
298
299 if(transmitpacket)
300 {
301 getTransmit(&p_sendData, &bytes_to_send);
302
303 ssize_t ret = UDP_socket->send(p_sendData, bytes_to_send, remoteipaddr);
304 if(ret < 0)
305 {
306 yError() << "Unable to send a message";
307 }
308 }
309
310 return true; // if false the program quits from the forever loop
311}
312
313
314
315// somebody passes the received packet - this is used just as an interface
316void BoardTransceiver::onMsgReception(uint8_t *data, uint16_t size)
317{
318 if(NULL == data)
319 {
320 yError() << "eo BoardTransceiver::onMsgReception() called with NULL data";
321 return;
322 }
323
324 yError() << "Received a message with size = " << size;
325
326
327 uint16_t numofrops;
328 uint64_t txtime;
329 uint16_t capacityrxpkt = 0;
330
331 // protezione per la scrittura dei dati all'interno della memoria del transceiver, su ricezione di un rop.
332 // il mutex e' unico per tutto il transceiver
333 eo_packet_Capacity_Get(p_RxPkt, &capacityrxpkt);
334 if(size > capacityrxpkt)
335 {
336 yError () << "received packet has size " << size << "which is higher than capacity of rx pkt = " << capacityrxpkt << "\n";
337 return;
338 }
339
340 eo_packet_Payload_Set(p_RxPkt, data, size);
341 eo_packet_Addressing_Set(p_RxPkt, remoteipaddr, remoteipport);
342 eo_transceiver_Receive(transceiver, p_RxPkt, &numofrops, &txtime);
343}
344
345
346
347/* This function just modify the pointer 'data', in order to point to transceiver's memory where a copy of the ropframe
348 * to be sent is stored.
349 * The memory holding this ropframe will be written ONLY in case of a new call of eo_transceiver_Transmit function,
350 * therefore it is safe to use it. No concurrency is involved here.
351 */
352void BoardTransceiver::getTransmit(uint8_t **data, uint16_t *size)
353{
354 if((NULL == data) || (NULL == size))
355 {
356 yError() << "eo BoardTransceiver::getTransmit() called with NULL data or size";
357 return;
358 }
359
360 uint16_t numofrops;
361 EOpacket* ptrpkt = NULL;
362 eOresult_t res;
363
364 *size = 0;
365 *data = NULL;
366
367
368 res = eo_transceiver_outpacket_Prepare(transceiver, &numofrops);
369 if(eores_OK != res)
370 {
371 yError() << "eo BoardTransceiver::getTransmit(): failure of eo_transceiver_outpacket_Prepare()";
372 return;
373 }
374
375 res = eo_transceiver_outpacket_Get(transceiver, &ptrpkt);
376 if(eores_OK != res)
377 {
378 yError() << "eo BoardTransceiver::getTransmit(): failure of eo_transceiver_outpacket_Get()";
379 return;
380 }
381
382 // now ptrpkt points to internal tx packet of the transceiver.
383 eo_packet_Payload_Get(ptrpkt, data, size);
384}
385
386
387
389{
390 return(protboardnumber);
391}
392
393
394void embOBJerror(eOerrmanErrorType_t errtype, eOid08_t taskid, const char *eobjstr, const char *info)
395{
396 static const char* theerrors[] = { "eo_errortype_info", "eo_errortype_warning", "eo_errortype_weak", "eo_errortype_fatal" };
397
398 yError() << "embOBJerror(): errtype = " << theerrors[errtype] << "from EOobject = " << eobjstr << " w/ message = " << info;
399
400 if(errtype == eo_errortype_fatal)
401 {
402 yError() << "embOBJerror(): FATAL ERROR: the calling thread shall now be stopped in a forever loop here inside";
403 for(;;);
404 }
405
406}
407
409{
410 // marco.accame: in here we init the embOBJ system for YARP.
411 eOerrman_cfg_t errmanconfig = {0};
412 errmanconfig.extfn.usr_on_error = embOBJerror;
413 const eOysystem_cfg_t *syscfg = NULL;
414 const eOmempool_cfg_t *mpoolcfg = NULL; // uses standard mode
415 //const eOerrman_cfg_t *errmancf = NULL; // uses default mode
416 eoy_sys_Initialise(syscfg, mpoolcfg, &errmanconfig);
417}
418
419bool BoardTransceiver::initProtocol(yarp::os::Searchable &config)
420{
421 static bool alreadyinitted = false;
422
423 if(false == alreadyinitted)
424 {
425 // before using embOBJ we need initialing its system. it is better to init it again in case someone did not do it
427
428 static const uint8_t numOfBoardsinRobot = eoprot_boards_maxnumberof; // to be initialise later or w/ a proper number from XML ...
429
430 // init the protocol to manage all boards of the robot
431 if(eores_OK != eoprot_config_board_numberof(numOfBoardsinRobot))
432 {
433 yError() << "BoardTransceiver::initProtocol(): call to eoprot_config_board_numberof() fails.";
434 return(false);
435 }
436
437 // configure all the callbacks of all endpoints.
438
439 eoprot_override_mn();
440 eoprot_override_mc();
441 eoprot_override_as();
442 eoprot_override_sk();
443
444 // ok. all is done correctly
445 alreadyinitted = true;
446
447 // yWarning() << "BoardTransceiver::initProtocol() CALLED W/ INITIALISATION";
448 }
449 else
450 {
451 // yWarning() << "BoardTransceiver::initProtocol() CALLED W/OUT INITIALISATION";
452 }
453
454 return(true);
455}
456
457extern "C" {
458void boardtransceiver_fun_UPDT_mn_appl_cmmnds_go2state(const EOnv* nv, const eOropdescriptor_t* rd);
459}
460
461void BoardTransceiver::eoprot_override_mn(void)
462{ // nothing to do
463
464 static const eOprot_callbacks_endpoint_descriptor_t mn_callbacks_descriptor_endp =
465 {
466 EO_INIT(.endpoint) eoprot_endpoint_management,
467 EO_INIT(.raminitialise) NULL // or any xxeoprot_fun_INITIALISE_mn
468 };
469
470 static const eOprot_callbacks_variable_descriptor_t mn_callbacks_descriptors_vars[] =
471 {
472 // appl
473 { //
474 EO_INIT(.endpoint) eoprot_endpoint_management,
475 EO_INIT(.entity) eoprot_entity_mn_appl,
476 EO_INIT(.tag) eoprot_tag_mn_appl_cmmnds_go2state,
477 EO_INIT(.init) NULL,
479 }
480 };
481
482
483 // ------------------------------------------------------------------------------------------------------------------------------------
484 // -- general ram initialise of sk endpoint called by every board.
485
486 // we dont do any general initialisation, even if we could do it with a xxeoprot_fun_INITIALISE_sk() function
487 //eoprot_config_callbacks_endpoint_set(&sk_callbacks_descriptor_endp);
488
489
490 // ------------------------------------------------------------------------------------------------------------------------------------
491 // -- override of the callbacks of variables of mc. common to every board. we use the id, even if the eoprot_config_variable_callback()
492 // operates on any index.
493
494 uint32_t number = sizeof(mn_callbacks_descriptors_vars)/sizeof(mn_callbacks_descriptors_vars[0]);
495 uint32_t i = 0;
496
497 for(i=0; i<number; i++)
498 {
499 eoprot_config_callbacks_variable_set(&mn_callbacks_descriptors_vars[i]);
500 }
501}
502
503extern "C" {
504void boardtransceiver_fun_UPDT_mc_joint_cmmnds_interactionmode(const EOnv* nv, const eOropdescriptor_t* rd);
505}
506
507void BoardTransceiver::eoprot_override_mc(void)
508{
509
510 static const eOprot_callbacks_endpoint_descriptor_t mc_callbacks_descriptor_endp =
511 {
512 EO_INIT(.endpoint) eoprot_endpoint_motioncontrol,
513 EO_INIT(.raminitialise) NULL // or any xxeoprot_fun_INITIALISE_mc
514 };
515
516 static const eOprot_callbacks_variable_descriptor_t mc_callbacks_descriptors_vars[] =
517 {
518 // joint
519#if 0
520 { // joint_config
521 EO_INIT(.endpoint) eoprot_endpoint_motioncontrol,
522 EO_INIT(.entity) eoprot_entity_mc_joint,
523 EO_INIT(.tag) eoprot_tag_mc_joint_config,
524 EO_INIT(.init) NULL,
525 EO_INIT(.update) eoprot_fun_UPDT_mc_joint_config
526 },
527 { // joint_config_pidposition
528 EO_INIT(.endpoint) eoprot_endpoint_motioncontrol,
529 EO_INIT(.entity) eoprot_entity_mc_joint,
530 EO_INIT(.tag) eoprot_tag_mc_joint_config_pidposition,
531 EO_INIT(.init) NULL,
532 EO_INIT(.update) eoprot_fun_UPDT_mc_joint_config_pidposition
533 },
534 { // joint_config_impedance
535 EO_INIT(.endpoint) eoprot_endpoint_motioncontrol,
536 EO_INIT(.entity) eoprot_entity_mc_joint,
537 EO_INIT(.tag) eoprot_tag_mc_joint_config_impedance,
538 EO_INIT(.init) NULL,
539 EO_INIT(.update) eoprot_fun_UPDT_mc_joint_config_impedance
540 },
541 { // joint_config_pidtorque
542 EO_INIT(.endpoint) eoprot_endpoint_motioncontrol,
543 EO_INIT(.entity) eoprot_entity_mc_joint,
544 EO_INIT(.tag) eoprot_tag_mc_joint_config_pidtorque,
545 EO_INIT(.init) NULL,
546 EO_INIT(.update) eoprot_fun_UPDT_mc_joint_config_pidtorque
547 },
548 { // joint_status
549 EO_INIT(.endpoint) eoprot_endpoint_motioncontrol,
550 EO_INIT(.entity) eoprot_entity_mc_joint,
551 EO_INIT(.tag) eoprot_tag_mc_joint_status,
552 EO_INIT(.init) NULL,
553 EO_INIT(.update) eoprot_fun_UPDT_mc_joint_status
554 },
555 { // joint_status_basic
556 EO_INIT(.endpoint) eoprot_endpoint_motioncontrol,
557 EO_INIT(.entity) eoprot_entity_mc_joint,
558 EO_INIT(.tag) eoprot_tag_mc_joint_status_basic,
559 EO_INIT(.init) NULL,
560 EO_INIT(.update) eoprot_fun_UPDT_mc_joint_status_basic
561 },
562 { // joint_cmmnds_setpoint731
563 EO_INIT(.endpoint) eoprot_endpoint_motioncontrol,
564 EO_INIT(.entity) eoprot_entity_mc_joint,
565 EO_INIT(.tag) eoprot_tag_mc_joint_cmmnds_setpoint,
566 EO_INIT(.init) NULL,
567 EO_INIT(.update) eoprot_fun_UPDT_mc_joint_cmmnds_setpoint
568 },
569 { // joint_config_limitsofjoint
570 EO_INIT(.endpoint) eoprot_endpoint_motioncontrol,
571 EO_INIT(.entity) eoprot_entity_mc_joint,
572 EO_INIT(.tag) eoprot_tag_mc_joint_config_limitsofjoint,
573 EO_INIT(.init) NULL,
574 EO_INIT(.update) eoprot_fun_UPDT_mc_joint_config_limitsofjoint
575 },
576 // motor
577 { // motor_config
578 EO_INIT(.endpoint) eoprot_endpoint_motioncontrol,
579 EO_INIT(.entity) eoprot_entity_mc_motor,
580 EO_INIT(.tag) eoprot_tag_mc_motor_config,
581 EO_INIT(.init) NULL,
582 EO_INIT(.update) eoprot_fun_UPDT_mc_motor_config
583 },
584 { // motor_config_maxcurrentofmotor
585 EO_INIT(.endpoint) eoprot_endpoint_motioncontrol,
586 EO_INIT(.entity) eoprot_entity_mc_motor,
587 EO_INIT(.tag) eoprot_tag_mc_motor_config_maxcurrentofmotor,
588 EO_INIT(.init) NULL,
589 EO_INIT(.update) eoprot_fun_UPDT_mc_motor_config_maxcurrentofmotor
590 },
591 { // motor_status_basic
592 EO_INIT(.endpoint) eoprot_endpoint_motioncontrol,
593 EO_INIT(.entity) eoprot_entity_mc_motor,
594 EO_INIT(.tag) eoprot_tag_mc_motor_status_basic,
595 EO_INIT(.init) NULL,
596 EO_INIT(.update) eoprot_fun_UPDT_mc_motor_status_basic
597 }
598#endif
599
600 // in here put what the ems needs to do when some variables arrive
601
602 { // ...............
603 EO_INIT(.endpoint) eoprot_endpoint_motioncontrol,
604 EO_INIT(.entity) eoprot_entity_mc_joint,
605 EO_INIT(.tag) eoprot_tag_mc_joint_cmmnds_interactionmode,
606 EO_INIT(.init) NULL,
608 }
609 };
610
611
612 // ------------------------------------------------------------------------------------------------------------------------------------
613 // -- general ram initialise of mc endpoint called by every board.
614
615 // we dont do any general initialisation, even if we could do it with a xxeoprot_fun_INITIALISE_mc() function
616 //eoprot_config_callbacks_endpoint_set(&mc_callbacks_descriptor_endp);
617
618
619 // ------------------------------------------------------------------------------------------------------------------------------------
620 // -- override of the callbacks of variables of mc. common to every board. we use the id, even if the eoprot_config_variable_callback()
621 // operates on any index.
622
623 uint32_t number = sizeof(mc_callbacks_descriptors_vars)/sizeof(mc_callbacks_descriptors_vars[0]);
624 uint32_t i = 0;
625
626 for(i=0; i<number; i++)
627 {
628 eoprot_config_callbacks_variable_set(&mc_callbacks_descriptors_vars[i]);
629 }
630
631}
632
633
634void BoardTransceiver::eoprot_override_as(void)
635{
636
637 // dont configure anything for now
638#if 0
639
640 static const eOprot_callbacks_endpoint_descriptor_t as_callbacks_descriptor_endp =
641 {
642 EO_INIT(.endpoint) eoprot_endpoint_analogsensors,
643 EO_INIT(.raminitialise) NULL // or any xxeoprot_fun_INITIALISE_as
644 };
645
646 static const eOprot_callbacks_variable_descriptor_t as_callbacks_descriptors_vars[] =
647 {
648 // strain
649 { // strain_status_calibratedvalues
650 EO_INIT(.endpoint) eoprot_endpoint_analogsensors,
651 EO_INIT(.entity) eoprot_entity_as_strain,
652 EO_INIT(.tag) eoprot_tag_as_strain_status_calibratedvalues,
653 EO_INIT(.init) NULL,
655 },
656 { // strain_status_uncalibratedvalues
657 EO_INIT(.endpoint) eoprot_endpoint_analogsensors,
658 EO_INIT(.entity) eoprot_entity_as_strain,
659 EO_INIT(.tag) eoprot_tag_as_strain_status_uncalibratedvalues,
660 EO_INIT(.init) NULL,
662 },
663 // mais
664 { // mais_status_the15values
665 EO_INIT(.endpoint) eoprot_endpoint_analogsensors,
666 EO_INIT(.entity) eoprot_entity_as_mais,
667 EO_INIT(.tag) eoprot_tag_as_mais_status_the15values,
668 EO_INIT(.init) NULL,
670 }
671 };
672
673
674 // ------------------------------------------------------------------------------------------------------------------------------------
675 // -- general ram initialise of as endpoint called by every board.
676
677 // we dont do any general initialisation, even if we could do it with a xxeoprot_fun_INITIALISE_as() function
678 //eoprot_config_callbacks_endpoint_set(&as_callbacks_descriptor_endp);
679
680
681
682 // ------------------------------------------------------------------------------------------------------------------------------------
683 // -- override of the callbacks of variables of mc. common to every board. we use the id, even if the eoprot_config_variable_callback()
684 // operates on any index.
685
686 uint32_t number = sizeof(as_callbacks_descriptors_vars)/sizeof(as_callbacks_descriptors_vars[0]);
687 uint32_t i = 0;
688
689 for(i=0; i<number; i++)
690 {
691 eoprot_config_callbacks_variable_set(&as_callbacks_descriptors_vars[i]);
692 }
693
694#endif
695}
696
697
698void BoardTransceiver::eoprot_override_sk(void)
699{
700 // dont configure anything for now
701#if 0
702 static const eOprot_callbacks_endpoint_descriptor_t sk_callbacks_descriptor_endp =
703 {
704 EO_INIT(.endpoint) eoprot_endpoint_skin,
705 EO_INIT(.raminitialise) NULL // or any xxeoprot_fun_INITIALISE_sk
706 };
707
708 static const eOprot_callbacks_variable_descriptor_t sk_callbacks_descriptors_vars[] =
709 {
710 // skin
711 { // strain_status_calibratedvalues
712 EO_INIT(.endpoint) eoprot_endpoint_skin,
713 EO_INIT(.entity) eoprot_entity_sk_skin,
714 EO_INIT(.tag) eoprot_tag_sk_skin_status_arrayof10canframes,
715 EO_INIT(.init) NULL,
716 EO_INIT(.update) eoprot_fun_UPDT_sk_skin_status_arrayof10canframes
717 }
718 };
719
720
721 // ------------------------------------------------------------------------------------------------------------------------------------
722 // -- general ram initialise of sk endpoint called by every board.
723
724 // we dont do any general initialisation, even if we could do it with a xxeoprot_fun_INITIALISE_sk() function
725 //eoprot_config_callbacks_endpoint_set(&sk_callbacks_descriptor_endp);
726
727
728 // ------------------------------------------------------------------------------------------------------------------------------------
729 // -- override of the callbacks of variables of mc. common to every board. we use the id, even if the eoprot_config_variable_callback()
730 // operates on any index.
731
732 uint32_t number = sizeof(sk_callbacks_descriptors_vars)/sizeof(sk_callbacks_descriptors_vars[0]);
733 uint32_t i = 0;
734
735 for(i=0; i<number; i++)
736 {
737 eoprot_config_callbacks_variable_set(&sk_callbacks_descriptors_vars[i]);
738 }
739#endif
740}
741
742
743void cpp_protocol_callback_incaseoferror_in_sequencenumberReceived(uint32_t remipv4addr, uint64_t rec_seqnum, uint64_t expected_seqnum)
744{
745 long long unsigned int exp = expected_seqnum;
746 long long unsigned int rec = rec_seqnum;
747 printf("Error in sequence number from 0x%x!!!! \t Expected %llu, received %llu\n", remipv4addr, exp, rec);
748};
749
750//extern "C" {
751//extern void protocol_callback_incaseoferror_in_sequencenumberReceived(uint32_t remipv4addr, uint64_t rec_seqnum, uint64_t expected_seqnum);
752//}
753
754
755bool BoardTransceiver::prepareTransceiverConfig(yarp::os::Searchable &config)
756{
757
758 memcpy(&devtxrxcfg, &eo_devicetransceiver_cfg_default, sizeof(eOdevicetransceiver_cfg_t));
759
760 // the nvsetcfg of the board ...
761 devtxrxcfg.nvsetdevcfg = getNVset_DEVcfg(config);
762
763 if(NULL == devtxrxcfg.nvsetdevcfg)
764 {
765 return(false);
766 }
767
768 devtxrxcfg.remotehostipv4addr = remoteipaddr;
769 devtxrxcfg.remotehostipv4port = remoteipport;
770
771
772 const eOtransceiver_sizes_t devsizes =
773 {
774 EO_INIT(.capacityoftxpacket) 1408,
775 EO_INIT(.capacityofrop) 256,
776 EO_INIT(.capacityofropframeregulars) 1024,
777 EO_INIT(.capacityofropframeoccasionals) 128,
778 EO_INIT(.capacityofropframereplies) 256,
779 EO_INIT(.maxnumberofregularrops) 32
780 };
781
782 memcpy(&devtxrxcfg.sizes, &devsizes, sizeof(eOtransceiver_sizes_t));
783
784
785
786
787 // other configurable parameters for eOhosttransceiver_cfg_t
788 // - mutex_fn_new, transprotection, nvsetprotection are left (NULL, eo_trans_protection_none, eo_nvset_protection_none)
789 // as in default because we dont protect internally w/ a mutex
790 // - proxycfg is left NULL as in default because we dont use a proxy.
791
792 // marco.accame on 29 apr 2014: so that the EOreceiver calls this funtion in case of error in sequence number
794
795
796 return(true);
797}
798
799
800
801
802const eOnvset_DEVcfg_t * BoardTransceiver::getNVset_DEVcfg(yarp::os::Searchable &config)
803{
804
805 const eOnvset_DEVcfg_t* nvsetdevcfg = NULL;
806
807
808
809 nvsetdevcfg = NULL;
810
811 eOprotconfig_cfg_t protcfg;
812 memcpy(&protcfg, &eo_protconfig_cfg_default, sizeof(eOprotconfig_cfg_t));
813 // ok, now i get the values from config and run ...
814
815 // at least ... this one
816 protcfg.board = get_protBRDnumber();
817
818 if(config.isNull())
819 {
820 yWarning() << "BoardTransceiver-> board " << get_protBRDnumber()+1 << " misses: entire PROTOCOL group ... using max capabilities";
821 //return false;
822 }
823 else
824 {
825 int number;
826
827 if(false == config.check("endpointManagementIsSupported"))
828 {
829 yWarning() << "BoardTransceiver-> board " << get_protBRDnumber()+1 << " misses: mandatory config of entire MN endpoint ... enabled w/ max capabilities" <<
830 " (comm, appl) = (" << protcfg.en_mn_entity_comm_numberof << ", " << protcfg.en_mn_entity_appl_numberof << ")";
831 }
832 else if((false == config.check("entityMNcommunicationNumberOf")) || (false == config.check("entityMNapplicationNumberOf")))
833 {
834 yWarning() << "BoardTransceiver-> board " << get_protBRDnumber()+1 << " misses: mandatory config of some MN entities ... using max capabilities" <<
835 " (comm, appl) = (" << protcfg.en_mn_entity_comm_numberof << ", " << protcfg.en_mn_entity_appl_numberof << ")";
836 }
837 else
838 {
839 // ok, retrieve the numbers ...
840 number = config.find("endpointManagementIsSupported").asInt32();
841 protcfg.ep_management_is_present = (0 == number) ? (eobool_false) : (eobool_true);
842 if(eobool_true == protcfg.ep_management_is_present)
843 {
844 protcfg.en_mn_entity_comm_numberof = config.find("entityMNcommunicationNumberOf").asInt32();
845 protcfg.en_mn_entity_appl_numberof = config.find("entityMNapplicationNumberOf").asInt32();
846 }
847 else
848 {
849 protcfg.en_mn_entity_comm_numberof = 0;
850 protcfg.en_mn_entity_appl_numberof = 0;
851 }
852 // sanity check
853 if((protcfg.en_mn_entity_comm_numberof > 1) || (protcfg.en_mn_entity_appl_numberof > 1))
854 {
855 yWarning() << "BoardTransceiver-> board " << get_protBRDnumber()+1 << " has: a strange number of MN entities" <<
856 " (comm, appl) = (" << protcfg.en_mn_entity_comm_numberof << ", " << protcfg.en_mn_entity_appl_numberof << ")";
857 }
858
859 }
860
861
862 if(false == config.check("endpointMotionControlIsSupported"))
863 {
864 yWarning() << "BoardTransceiver-> board " << get_protBRDnumber()+1 << " misses: mandatory config of entire MC endpoint ... enabled w/ max capabilities" <<
865 " (joint, motor, contr) = (" << protcfg.en_mc_entity_joint_numberof << ", " << protcfg.en_mc_entity_motor_numberof <<
866 ", " << protcfg.en_mc_entity_controller_numberof << ")";
867 }
868 else if((false == config.check("entityMCjointNumberOf")) || (false == config.check("entityMCmotorNumberOf")) ||
869 (false == config.check("entityMCmotorNumberOf")))
870 {
871 yWarning() << "BoardTransceiver-> board " << get_protBRDnumber()+1 << " misses: mandatory config of some MC entities ... using max capabilities" <<
872 " (joint, motor, contr) = (" << protcfg.en_mc_entity_joint_numberof << ", " << protcfg.en_mc_entity_motor_numberof <<
873 ", " << protcfg.en_mc_entity_controller_numberof << ")";
874 }
875 else
876 {
877 number = config.find("endpointMotionControlIsSupported").asInt32();
878 protcfg.ep_motioncontrol_is_present = (0 == number) ? (eobool_false) : (eobool_true);
879 if(eobool_true == protcfg.ep_motioncontrol_is_present)
880 {
881 protcfg.en_mc_entity_joint_numberof = config.find("entityMCjointNumberOf").asInt32();
882 protcfg.en_mc_entity_motor_numberof = config.find("entityMCmotorNumberOf").asInt32();
883 protcfg.en_mc_entity_controller_numberof = config.find("entityMCcontrollerNumberOf").asInt32();
884 }
885 else
886 {
887 protcfg.en_mc_entity_joint_numberof = 0;
888 protcfg.en_mc_entity_motor_numberof = 0;
889 protcfg.en_mc_entity_controller_numberof = 0;
890 }
891 // sanity check
892 if((protcfg.en_mc_entity_joint_numberof > 16) || (protcfg.en_mc_entity_motor_numberof > 16) ||
893 (protcfg.en_mc_entity_controller_numberof > 1))
894 {
895 yWarning() << "BoardTransceiver-> board " << get_protBRDnumber()+1 << " has: a strange number of MC entities" <<
896 " (joint, motor, contr) = (" << protcfg.en_mc_entity_joint_numberof << ", " << protcfg.en_mc_entity_motor_numberof <<
897 ", " << protcfg.en_mc_entity_controller_numberof << ")";
898 }
899 }
900
901
902 if(false == config.check("endpointAnalogSensorsIsSupported"))
903 {
904 yWarning() << "BoardTransceiver-> board " << get_protBRDnumber()+1 << " misses: mandatory config of entire AS endpoint ... enabled w/ max capabilities" <<
905 " (strain, mais, extorque) = (" << protcfg.en_as_entity_strain_numberof << ", " << protcfg.en_as_entity_mais_numberof <<
906 ", " << protcfg.en_as_entity_extorque_numberof << ")";
907 }
908 else if((false == config.check("entityASstrainNumberOf")) || (false == config.check("entityASmaisNumberOf")) ||
909 (false == config.check("entityASextorqueNumberOf")))
910 {
911 yWarning() << "BoardTransceiver-> board " << get_protBRDnumber()+1 << " misses: mandatory config of some AS entities ... using max capabilities" <<
912 " (strain, mais, extorque) = (" << protcfg.en_as_entity_strain_numberof << ", " << protcfg.en_as_entity_mais_numberof <<
913 ", " << protcfg.en_as_entity_extorque_numberof << ")";
914 }
915 else
916 {
917 number = config.find("endpointAnalogSensorsIsSupported").asInt32();
918 protcfg.ep_analogsensors_is_present = (0 == number) ? (eobool_false) : (eobool_true);
919 if(eobool_true == protcfg.ep_analogsensors_is_present)
920 {
921 protcfg.en_as_entity_strain_numberof = config.find("entityASstrainNumberOf").asInt32();
922 protcfg.en_as_entity_mais_numberof = config.find("entityASmaisNumberOf").asInt32();
923 protcfg.en_as_entity_extorque_numberof = config.find("entityASextorqueNumberOf").asInt32();
924 }
925 else
926 {
927 protcfg.en_as_entity_strain_numberof = 0;
928 protcfg.en_as_entity_mais_numberof = 0;
929 protcfg.en_as_entity_extorque_numberof = 0;
930 }
931 // sanity check
932 if((protcfg.en_as_entity_strain_numberof > 1) || (protcfg.en_as_entity_mais_numberof > 1) ||
933 (protcfg.en_as_entity_extorque_numberof > 16))
934 {
935 yWarning() << "BoardTransceiver-> board " << get_protBRDnumber()+1 << " has: a strange number of AS entities" <<
936 " (strain, mais, extorque) = (" << protcfg.en_as_entity_strain_numberof << ", " << protcfg.en_as_entity_mais_numberof <<
937 ", " << protcfg.en_as_entity_extorque_numberof << ")";
938 }
939 }
940
941
942 if(false == config.check("endpointSkinIsSupported"))
943 {
944 yWarning() << "BoardTransceiver-> board " << get_protBRDnumber()+1 << " misses: mandatory config of entire SK endpoint ... enabled w/ max capabilities" <<
945 " (skin) = (" << protcfg.en_sk_entity_skin_numberof << ")";
946 }
947 else if((false == config.check("entitySKskinNumberOf")))
948 {
949 yWarning() << "BoardTransceiver-> board " << get_protBRDnumber()+1 << " misses: mandatory config of some SK entities ... using max capabilities" <<
950 " (skin) = (" << protcfg.en_sk_entity_skin_numberof << ")";
951 }
952 else
953 {
954 number = config.find("endpointSkinIsSupported").asInt32();
955 protcfg.ep_skin_is_present = (0 == number) ? (eobool_false) : (eobool_true);
956 if(eobool_true == protcfg.ep_skin_is_present)
957 {
958 protcfg.en_sk_entity_skin_numberof = config.find("entitySKskinNumberOf").asInt32();
959 }
960 else
961 {
962 protcfg.en_sk_entity_skin_numberof = 0;
963 }
964 // sanity check
965 if((protcfg.en_sk_entity_skin_numberof > 2))
966 {
967 yWarning() << "BoardTransceiver-> board " << get_protBRDnumber()+1 << " has: a strange number of SK entities" <<
968 " (skin) = (" << protcfg.en_sk_entity_skin_numberof << ")";
969 }
970
971 }
972
973 printf("\nprotcfg --> bdr %d, mn = %d, mc = %d, as = %d, sk = %d ... co = %d, ap = %d, jn = %d, mt = %d, ct = %d, st = %d, ma = %d, ex = %d, sk = %d\n",
974 protcfg.board,
975 protcfg.ep_management_is_present, protcfg.ep_motioncontrol_is_present, protcfg.ep_analogsensors_is_present, protcfg.ep_skin_is_present,
976 protcfg.en_mn_entity_comm_numberof, protcfg.en_mn_entity_appl_numberof,
977 protcfg.en_mc_entity_joint_numberof, protcfg.en_mc_entity_motor_numberof, protcfg.en_mc_entity_controller_numberof,
978 protcfg.en_as_entity_strain_numberof, protcfg.en_as_entity_mais_numberof, protcfg.en_as_entity_extorque_numberof,
979 protcfg.en_sk_entity_skin_numberof
980 );
981
982
983 }
984
985
986
987 nvsetdevcfg = eo_protconfig_DEVcfg_Get(eo_protconfig_New(&protcfg));
988
989
990 if(NULL == nvsetdevcfg)
991 {
992 yError() << "BoardTransceiver::getNVset_DEVcfg() -> FAILS as it produces a NULL result";
993 }
994
995 return(nvsetdevcfg);
996}
997
998#if 0
999void boardtransceiver_fun_UPDT_mn_appl_cmmnds_go2state(const EOnv* nv, const eOropdescriptor_t* rd)
1000{
1001 eOmn_appl_state_t *newstate_ptr = (eOmn_appl_state_t *)rd->data;
1002
1003 switch(*newstate_ptr)
1004 {
1005 case applstate_running:
1006 case applstate_config:
1007 case applstate_error:
1008 {
1009 //applstate = *newstate_ptr;
1010 } break;
1011 }
1012}
1013
1014void boardtransceiver_fun_UPDT_mc_joint_cmmnds_interactionmode(const EOnv* nv, const eOropdescriptor_t* rd)
1015{
1016 EOnv_hid aNV = {0};
1017 eOnvBRD_t brd = eo_nv_GetBRD(nv);
1018
1019 EOnvSet* mynvset = arrayofnvsets[brd];
1020
1021 eOprotIndex_t index = eoprot_ID2index(rd->id32);
1022 eOenum08_t* pmode = (eOenum08_t*) rd->data;
1023
1024 eOnvID32_t id32status = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, index, eoprot_tag_mc_joint_status);
1025 eo_nvset_NV_Get(mynvset, eok_ipv4addr_localhost, id32status, &aNV);
1026
1027 eOmc_joint_status_t jointstatus = {0};
1028 uint16_t size = 0;
1029
1030 eOresult_t res = eo_nv_Get(&aNV, eo_nv_strg_volatile, &jointstatus, &size);
1031 jointstatus.interactionmodestatus = *pmode;
1032 eo_nv_Set(&aNV, &jointstatus, eobool_true, eo_nv_upd_dontdo);
1033
1034}
1035#endif
1036
1037// eof
1038
1039
1040
void eoprot_fun_UPDT_as_strain_status_calibratedvalues(const EOnv *nv, const eOropdescriptor_t *rd)
void eoprot_fun_UPDT_as_strain_status_uncalibratedvalues(const EOnv *nv, const eOropdescriptor_t *rd)
void eoprot_fun_UPDT_as_mais_status_the15values(const EOnv *nv, const eOropdescriptor_t *rd)
void eoprot_fun_UPDT_mc_joint_status(const EOnv *nv, const eOropdescriptor_t *rd)
@ data
void cpp_protocol_callback_incaseoferror_in_sequencenumberReceived(uint32_t remipv4addr, uint64_t rec_seqnum, uint64_t expected_seqnum)
EOnvSet * arrayofnvsets[16]
void boardtransceiver_fun_UPDT_mn_appl_cmmnds_go2state(const EOnv *nv, const eOropdescriptor_t *rd)
void embOBJerror(eOerrmanErrorType_t errtype, eOid08_t taskid, const char *eobjstr, const char *info)
void eoy_initialise(void)
void boardtransceiver_fun_UPDT_mc_joint_cmmnds_interactionmode(const EOnv *nv, const eOropdescriptor_t *rd)
EOnvSet * arrayofnvsets[]
void boardtransceiver_fun_UPDT_mn_appl_cmmnds_go2state(const EOnv *nv, const eOropdescriptor_t *rd)
void boardtransceiver_fun_UPDT_mc_joint_cmmnds_interactionmode(const EOnv *nv, const eOropdescriptor_t *rd)
exp(-x3 *T)]
ACE_UINT64 txtime
#define RECV_BUFFER_SIZE
EOtransceiver * transceiver
eOmn_appl_status_t * pApplStatus
virtual void onMsgReception(uint8_t *data, uint16_t size)
EOdeviceTransceiver * devtxrx
bool init(yarp::os::Searchable &config, uint32_t localipaddr, uint32_t remoteipaddr, uint16_t ipport, uint16_t pktsize, FEAT_boardnumber_t board_n)
bool createSocket(ACE_INET_Addr local_addr)
bool configure(yarp::os::ResourceFinder &rf)
void fromDouble(ACE_Time_Value &v, double x, int unit)
void getTransmit(uint8_t **data, uint16_t *size)
ACE_SOCK_Dgram * UDP_socket
eOdevicetransceiver_cfg_t devtxrxcfg
eOprotBRD_t protboardnumber
eOprotBRD_t get_protBRDnumber(void)
void cpp_protocol_callback_incaseoferror_in_sequencenumberReceived(EOreceiver *r)
FEAT_ip_addr EMSipAddr
FEAT_ip_addr PC104ipAddr
eOprotBRD_t featIdBoardNum2nvBoardNum(FEAT_boardnumber_t fid_boardnum)
uint8_t FEAT_boardnumber_t