Skip to content

Commit

Permalink
Basic bidirectional communication (PX4#5)
Browse files Browse the repository at this point in the history
* Support for multiple topics uORB -> FastRTPS

* Changed README to work with multiple topics

* README fix

* minor changes

* Basic bidirectional communication

* Merge fix

* Updated instructions and added a UART node
  • Loading branch information
vilhjalmur89 authored and VicenteEprosima committed Apr 6, 2017
1 parent 724518b commit 2ef1c57
Show file tree
Hide file tree
Showing 11 changed files with 763 additions and 22 deletions.
7 changes: 5 additions & 2 deletions README_eprosima.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,12 @@ Steps to use the auto generated application:
$ mkdir src/examples/micrortps_transmitter
$ cp msgenerated/general_uRTPS_UART_transmitter.cpp src/examples/micrortps_transmitter
- Also copy and rename the CMakeList to the example folder:
- Also copy and rename the CMakeList UART_Node to the example folder:

.. code-block:: shell
$ cp msgenerated/general_transmitter_CMakeLists.txt src/examples/micrortps_transmitter/CMakeLists.txt
$ cp msg/templates/urtps/UART_node.* src/examples/micrortps_transmitter/
- Construct and upload the firmware executing:

Expand Down Expand Up @@ -112,6 +113,7 @@ For create the application:
$ mkdir my_app && cd my_app
$ cp /path/to/Firmware/msgenerated/*.idl .
$ cp /path/to/Firmware/msgenerated/general_uRTPS_UART_receiver.* .
$ cp msg/templates/urtps/UART_node.* .
- Generate the base application with *fastrtpsgen*:

Expand All @@ -136,7 +138,7 @@ For create the application:
Now we need to do some modifications to use the both codes together.
Add a publish method to all publisher on that way:
Add a publish method to all publisher

- *sensor_combined_Publisher.h*

Expand Down Expand Up @@ -178,6 +180,7 @@ Add a publish method to all publisher on that way:
return 0;
}
- In *sensor_combined_Subscriber.cxx* we can add some code to print some info on the screen, for example:
.. code-block:: shell
Expand Down
19 changes: 17 additions & 2 deletions Tools/generate_microRTPS_support_general.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,30 @@
uorb_templates_dir = root_path + "/msg/templates/uorb"
urtps_templates_dir = root_path + "/msg/templates/urtps"

for msg_file in msg_files:
px_generate_uorb_topic_files.generate_idl_file(msg_file, out_dir, urtps_templates_dir, px_generate_uorb_topic_files.INCL_DEFAULT)


uRTPS_TRANS_APP_GEN_TEMPL_FILE = 'general_uRTPS_UART_transmitter.cpp.template'
uRTPS_TRANS_CML_GEN_TEMPL_FILE = 'general_transmitter_CMakeLists.txt.template'
uRTPS_RECEV_H_GEN_TEMPL_FILE = 'general_uRTPS_UART_receiver.h.template'
uRTPS_RECEV_SRC_GEN_TEMPL_FILE = 'general_uRTPS_UART_receiver.cxx.template'
uRTPS_PUBSUBMAIN_GEN_TEMPL_FILE = 'general_uRTPS_UART_PubSubMain.cxx.template'
uRTPS_PUBLISHER_SRC_TEMPL_FILE = 'Publisher.cxx.template'
uRTPS_PUBLISHER_H_TEMPL_FILE = 'Publisher.h.template'
uRTPS_SUBSCRIBER_SRC_TEMPL_FILE = 'Subscriber.cxx.template'
uRTPS_SUBSCRIBER_H_TEMPL_FILE = 'Subscriber.h.template'


for msg_file in msg_files:
px_generate_uorb_topic_files.generate_idl_file(msg_file, out_dir, urtps_templates_dir,
px_generate_uorb_topic_files.INCL_DEFAULT)
px_generate_uorb_topic_files.generate_topic_file(msg_file, out_dir, urtps_templates_dir,
px_generate_uorb_topic_files.INCL_DEFAULT, uRTPS_PUBLISHER_SRC_TEMPL_FILE)
px_generate_uorb_topic_files.generate_topic_file(msg_file, out_dir, urtps_templates_dir,
px_generate_uorb_topic_files.INCL_DEFAULT, uRTPS_PUBLISHER_H_TEMPL_FILE)
px_generate_uorb_topic_files.generate_topic_file(msg_file, out_dir, urtps_templates_dir,
px_generate_uorb_topic_files.INCL_DEFAULT, uRTPS_SUBSCRIBER_SRC_TEMPL_FILE)
px_generate_uorb_topic_files.generate_topic_file(msg_file, out_dir, urtps_templates_dir,
px_generate_uorb_topic_files.INCL_DEFAULT, uRTPS_SUBSCRIBER_H_TEMPL_FILE)

px_generate_uorb_topic_files.generate_uRTPS_general(msg_files, out_dir, uorb_templates_dir,
px_generate_uorb_topic_files.INCL_DEFAULT, uRTPS_TRANS_APP_GEN_TEMPL_FILE)
Expand Down
35 changes: 35 additions & 0 deletions Tools/px_generate_uorb_topic_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,41 @@ def generate_uRTPS_general(filename_msgs, outputdir, templatedir, includepath, t
return generate_by_template(output_file, template_file, merged_em_globals)




def generate_topic_file(filename_msg, outputdir, templatedir, includepath, template_name):
"""
Generates an .idl from .msg file
"""
em_globals = get_em_globals(filename_msg, includepath)
spec_short_name = em_globals["spec"].short_name

# Make sure output directory exists:
if not os.path.isdir(outputdir):
os.makedirs(outputdir)

template_file = os.path.join(templatedir, template_name)
output_file = os.path.join(outputdir, spec_short_name + "_" + template_name.replace(".template", ""))

return generate_by_template(output_file, template_file, em_globals)

def generate_uRTPS_general(filename_msgs, outputdir, templatedir, includepath, template_name):
"""
Generates source file by UART msg content
"""
em_globals_list = [get_em_globals(f, includepath) for f in filename_msgs]
merged_em_globals = merge_em_globals_list(em_globals_list)

# Make sure output directory exists:
if not os.path.isdir(outputdir):
os.makedirs(outputdir)

template_file = os.path.join(templatedir, template_name)
output_file = os.path.join(outputdir, template_name.replace(".template", ""))

return generate_by_template(output_file, template_file, merged_em_globals)


def get_em_globals(filename_msg, includepath):
"""
Generates em globals dictionary
Expand Down
43 changes: 33 additions & 10 deletions msg/templates/uorb/general_uRTPS_UART_transmitter.cpp.template
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,13 @@ num_topics = len(topic_names)
#include <string.h>
#include <termios.h>


#include <microcdr/microCdr.h>
#include <uORB/uORB.h>

#include "UART_node.h"


@[for topic in topic_names]
#include <uORB/topics/@(topic).h>
@[end for]
Expand All @@ -44,7 +48,10 @@ int general_trans_main(int argc, char *argv[])
errx(1, "need a serial port name as argument");
}

int serial_fd = uart_init(argv[1], 115200);
UART_node m_uartNode;
m_uartNode.init_uart(argv[1]);
char rx_buffer[210];
char buffer[MICROCDR_INIT_BUF_LENGTH];

/* subscribe to topics */
px4_pollfd_struct_t fds[@(num_topics)];
Expand All @@ -60,7 +67,7 @@ int general_trans_main(int argc, char *argv[])

for (int i = 0; i < 50; ++i)
{
int poll_ret = px4_poll(fds, 2, 1000);
int poll_ret = px4_poll(fds, @(num_topics), 1000);

if (poll_ret == 0)
{
Expand All @@ -84,22 +91,38 @@ int general_trans_main(int argc, char *argv[])
/* copy raw data into local buffer */
orb_copy(ORB_ID(@(topic)), @(topic)_fd, &data);

char buffer[MICROCDR_INIT_BUF_LENGTH];
uint32_t length = 0;
serialize_@(topic)(&data, buffer, &length);

// Write serialized data trough UART
dprintf(serial_fd, ">>>");
dprintf(serial_fd, "%c", @(id)); // topic_ID
write(serial_fd, buffer, length);
dprintf(serial_fd, "<<<");

printf("<-@(id): ");
for (int c=0; c < 20; ++c) printf("%d ", buffer[c]);
printf("\n");
m_uartNode.writeToUART((char)@(id), buffer, length);
}
@[end for]
}
}

char topic_ID = 255;
uint8_t ret = m_uartNode.readFromUART(&topic_ID, rx_buffer, rx_buffer);
if (0 == ret)
{
@[for id, topic in enumerate(topic_names)]
if (topic_IC == id) {
printf("->%d: ", topic_ID);
for (int c=0; c < 20; ++c) printf("%d ", buffer[c]);
printf("\n");
// printf("Received @(topic) \n");

// struct @(topic)_s data;
// deserialize_@(topic)(&data, buffer);
// publish...
}
@[end for]
}
usleep(10000);
}
PX4_INFO("exiting");
close(serial_fd);
fflush(stdout);
return OK;
}
Expand Down
139 changes: 139 additions & 0 deletions msg/templates/urtps/Publisher.cxx.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
@###############################################
@#
@# EmPy template for generating <msg>_uRTPS_UART.cpp file
@#
@###############################################
@# Start of Template
@#
@# Context:
@# - msgs (List) list of all msg files
@# - multi_topics (List) list of all multi-topic names
@###############################################
@{
import genmsg.msgs
import gencpp
from px_generate_uorb_topic_helper import * # this is in Tools/

topic = spec.short_name
}@
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/*!
* @file @(topic)_Publisher.cpp
* This file contains the implementation of the publisher functions.
*
* This file was generated by the tool fastcdrgen.
*/


#include <fastrtps/participant/Participant.h>
#include <fastrtps/attributes/ParticipantAttributes.h>
#include <fastrtps/publisher/Publisher.h>
#include <fastrtps/attributes/PublisherAttributes.h>

#include <fastrtps/Domain.h>

#include <fastrtps/utils/eClock.h>

#include "@(topic)_Publisher.h"




@(topic)_Publisher::@(topic)_Publisher() : mp_participant(nullptr), mp_publisher(nullptr) {}

@(topic)_Publisher::~@(topic)_Publisher() { Domain::removeParticipant(mp_participant);}

bool @(topic)_Publisher::init()
{
// Create RTPSParticipant

ParticipantAttributes PParam;
PParam.rtps.builtin.domainId = 0;
PParam.rtps.builtin.leaseDuration = c_TimeInfinite;
PParam.rtps.setName("Participant_publisher"); //You can put here the name you want
mp_participant = Domain::createParticipant(PParam);
if(mp_participant == nullptr)
return false;

//Register the type

Domain::registerType(mp_participant,(TopicDataType*) &myType);

// Create Publisher

PublisherAttributes Wparam;
Wparam.topic.topicKind = NO_KEY;
Wparam.topic.topicDataType = myType.getName(); //This type MUST be registered
Wparam.topic.topicName = "@(topic)_PubSubTopic";
mp_publisher = Domain::createPublisher(mp_participant,Wparam,(PublisherListener*)&m_listener);
if(mp_publisher == nullptr)
return false;
cout << "Publisher created, waiting for Subscribers." << endl;
return true;
}

void @(topic)_Publisher::PubListener::onPublicationMatched(Publisher* pub,MatchingInfo& info)
{
if (info.status == MATCHED_MATCHING)
{
n_matched++;
cout << "Publisher matched" << endl;
}
else
{
n_matched--;
cout << "Publisher unmatched" << endl;
}
}

void @(topic)_Publisher::run()
{
while(m_listener.n_matched == 0)
{
eClock::my_sleep(250); // Sleep 250 ms
}

// Publication code

@(topic)_ st;

/* Initialize your structure here */

int msgsent = 0;
char ch = 'y';
do
{
if(ch == 'y')
{
mp_publisher->write(&st); ++msgsent;
cout << "Sending sample, count=" << msgsent << ", send another sample?(y-yes,n-stop): ";
}
else if(ch == 'n')
{
cout << "Stopping execution " << endl;
break;
}
else
{
cout << "Command " << ch << " not recognized, please enter \"y/n\":";
}
}while(std::cin >> ch);
}

void @(topic)_Publisher::publish(@(topic)_* st)
{
mp_publisher->write(st);
}
Loading

0 comments on commit 2ef1c57

Please sign in to comment.