Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Q
qgroundcontrol
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Valentin Platzgummer
qgroundcontrol
Commits
585c0b82
Commit
585c0b82
authored
Aug 06, 2020
by
Valentin Platzgummer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
RosBridgeClient::advertise mod
parent
4f76dc12
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
97 additions
and
13 deletions
+97
-13
RosBridgeClient.h
src/comm/ros_bridge/include/RosBridgeClient.h
+97
-13
No files found.
src/comm/ros_bridge/include/RosBridgeClient.h
View file @
585c0b82
...
...
@@ -47,6 +47,9 @@ class RosbridgeWsClient
std
::
deque
<
TopicData
>
advertised_topics_list
;
std
::
mutex
mutex
;
// Set to true on construction and to false on destruction. Used to notify independet threads.
std
::
shared_ptr
<
std
::
atomic_bool
>
alive
;
void
start
(
const
std
::
string
&
client_name
,
std
::
shared_ptr
<
WsClient
>
client
,
const
std
::
string
&
message
)
{
if
(
!
client
->
on_open
)
...
...
@@ -109,7 +112,8 @@ class RosbridgeWsClient
}
public:
RosbridgeWsClient
(
const
std
::
string
&
server_port_path
)
RosbridgeWsClient
(
const
std
::
string
&
server_port_path
)
:
alive
(
std
::
make_shared
<
std
::
atomic_bool
>
(
true
))
{
this
->
server_port_path
=
server_port_path
;
}
...
...
@@ -124,6 +128,7 @@ public:
{
removeClient
(
client
.
first
);
}
alive
->
store
(
false
);
}
// The execution can take up to 100 ms!
...
...
@@ -235,6 +240,50 @@ public:
#endif
}
//!
//! \brief Returns a string containing all advertised topics.
//! \return Returns a string containing all advertised topics.
//!
//! \note This function will wait until the /rosapi/topics service is available.
//! \note Call connected() in advance to ensure that a connection was established.
//!
std
::
string
get_advertised_topics
(){
this
->
waitForService
(
"/rosapi/topics"
);
std
::
shared_ptr
<
std
::
promise
<
std
::
string
>>
promise
;
auto
future
=
promise
->
get_future
();
// Call /rosapi/topics to see if topic is already available.
this
->
callService
(
"/rosapi/topics"
,
[
promise
](
std
::
shared_ptr
<
WsClient
::
Connection
>
connection
,
std
::
shared_ptr
<
WsClient
::
InMessage
>
in_message
){
promise
->
set_value
(
in_message
->
string
());
connection
->
send_close
(
1000
);
});
future
.
wait
();
return
future
.
get
();
}
//!
//! \brief Returns a string containing all advertised services.
//! \return Returns a string containing all advertised services.
//!
//! \note This function will wait until the /rosapi/services service is available.
//! \note Call connected() in advance to ensure that a connection was established.
//!
std
::
string
get_advertised_services
(){
this
->
waitForService
(
"/rosapi/services"
);
std
::
shared_ptr
<
std
::
promise
<
std
::
string
>>
promise
;
auto
future
=
promise
->
get_future
();
// Call /rosapi/services to see if topic is already available.
this
->
callService
(
"/rosapi/services"
,
[
promise
](
std
::
shared_ptr
<
WsClient
::
Connection
>
connection
,
std
::
shared_ptr
<
WsClient
::
InMessage
>
in_message
){
promise
->
set_value
(
in_message
->
string
());
connection
->
send_close
(
1000
);
});
future
.
wait
();
return
future
.
get
();
}
// Gets the client from client_map and starts it. Advertising is essentially sending a message.
// One client per topic!
void
advertise
(
const
std
::
string
&
client_name
,
const
std
::
string
&
topic
,
const
std
::
string
&
type
,
const
std
::
string
&
id
=
""
)
...
...
@@ -266,9 +315,9 @@ public:
message
=
"{"
+
message
+
"}"
;
#ifdef DEBUG
client
->
on_open
=
[
client_name
,
message
,
ready
](
std
::
shared_ptr
<
WsClient
::
Connection
>
connection
)
{
client
->
on_open
=
[
this
,
topic
,
message
,
ready
,
client_name
](
std
::
shared_ptr
<
WsClient
::
Connection
>
connection
)
{
#else
client
->
on_open
=
[
message
,
ready
](
std
::
shared_ptr
<
WsClient
::
Connection
>
connection
)
{
client
->
on_open
=
[
this
,
topic
,
message
,
ready
](
std
::
shared_ptr
<
WsClient
::
Connection
>
connection
)
{
#endif
#ifdef DEBUG
...
...
@@ -276,11 +325,22 @@ public:
std
::
cout
<<
client_name
<<
": Sending message: "
<<
message
<<
std
::
endl
;
#endif
connection
->
send
(
message
);
// Wait for rosbridge_server to process the request and mark topic as "ready".
// This could be avoided by waiting for a status message. However, at the time of
// writing rosbridge_server status messages are still experimental.
std
::
this_thread
::
sleep_for
(
std
::
chrono
::
milliseconds
(
500
));
ready
->
store
(
true
);
// Now wait until topic is successfully advertised.
while
(
true
){
std
::
this_thread
::
sleep_for
(
std
::
chrono
::
milliseconds
(
100
));
std
::
string
advertised_topics
=
this
->
get_advertised_topics
();
auto
pos
=
advertised_topics
.
find
(
topic
);
if
(
pos
!=
std
::
string
::
npos
){
// topic advertised!
#ifdef DEBUG
std
::
cout
<<
client_name
<<
": topic "
<<
topic
<<
"successfully advertised"
<<
std
::
endl
;
#endif
break
;
}
#ifdef DEBUG
std
::
cout
<<
client_name
<<
": waiting for topic "
<<
topic
<<
"to be advertised"
<<
std
::
endl
;
#endif
}
ready
->
store
(
true
);
// Mark topic as successfully advertised.
};
start
(
client_name
,
client
,
message
);
...
...
@@ -386,8 +446,8 @@ public:
std
::
cout
<<
client_name
<<
": Sending message."
<<
std
::
endl
;
//std::cout << client_name << ": Sending message: " << message << std::endl;
#endif
while
(
!
ready
->
load
()
){
// Wait for the topic to be advertised.
std
::
this_thread
::
sleep_for
(
std
::
chrono
::
milliseconds
(
5
00
));
while
(
!
ready
->
load
()
){
// Wait for the topic to be
successfully
advertised.
std
::
this_thread
::
sleep_for
(
std
::
chrono
::
milliseconds
(
1
00
));
}
connection
->
send
(
message
);
...
...
@@ -430,10 +490,34 @@ public:
{
message
+=
",
\"
compression
\"
:
\"
"
+
compression
+
"
\"
"
;
}
message
=
"{"
+
message
+
"}"
;
message
=
"{"
+
message
+
"}"
;
auto
client
=
it
->
second
;
client
->
on_message
=
callback
;
const
auto
cAlive
=
this
->
alive
;
// Start thread to wait for topic to be advertised.
std
::
thread
t
([
this
,
client_name
,
client
,
message
,
cAlive
,
topic
](){
while
(
cAlive
->
load
()){
// RosBridgeClient alive?
auto
advertised_topics
=
this
->
get_advertised_topics
();
auto
pos
=
advertised_topics
.
find
(
topic
);
if
(
pos
!=
std
::
string
::
npos
){
// desired topic available!
#ifdef DEBUG
std
::
cout
<<
client_name
<<
": topic "
<<
topic
<<
"available"
<<
std
::
endl
;
#endif
break
;
}
#ifdef DEBUG
std
::
cout
<<
client_name
<<
": waiting for topic "
<<
topic
<<
std
::
endl
;
#endif
std
::
this_thread
::
sleep_for
(
std
::
chrono
::
seconds
(
1
));
}
it
->
second
->
on_message
=
callback
;
start
(
client_name
,
it
->
second
,
message
);
if
(
cAlive
->
load
()
){
this
->
start
(
client_name
,
client
,
message
);
// subscribe to topic
}
});
t
.
detach
();
}
#ifdef DEBUG
else
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment