pydrake- Error when connecting IiwaCommandSender to LcmPublisherSystem - drake

I have the following lines in my program-
lcm = DrakeLcm()
lcm_command_sender = builder.AddSystem(IiwaCommandSender())
lcm_publisher = builder.AddSystem(LcmPublisherSystem.Make(channel="IIWA_COMMAND", lcm_type=lcmt_iiwa_command, lcm=lcm, publish_period=0.01))
//Connect controller to command sender
builder.Connect(controller.GetOutputPort("joint_positions"), lcm_command_sender.get_position_input_port())
//Connect lcm command sender to publisher
builder.Connect(lcm_command_sender.GetOutputPort("lcmt_iiwa_command"), lcm_publisher.get_input_port())
Upon running, the last line gives the following runtime error-
RuntimeError: DiagramBuilder::Connect: Mismatched value types while connecting output port lcmt_iiwa_command of System lcm_command_sender (type drake::lcmt_iiwa_command) to input port lcm_message of System LcmPublisherSystem(IIWA_COMMAND) (type drake::pydrake::Object)
I am not sure why this happens, since the documentation specifically says that the output port of IiwaCommandSender should be connected to the input port of LcmPublisherSystem, and both of them are of the type AbstractValue. What is it that I'm missing?

In the code above, the output port of the IiwaCommandSender is of type "drake::lcmt_iiwa_command" (a C++ class wrapped in Python), but the input port of the LcmPublisherSystem is of type "drake.lcmt_iiwa_command" (a Python class). Those are two different runtime types, even though they both represent an LCM message.
In this case, you should set use_cpp_serializer=True when calling LcmPublisherSystem.Make so that the input port is the C++ type, instead of the Python type.
https://drake.mit.edu/pydrake/pydrake.systems.lcm.html#pydrake.systems.lcm.LcmPublisherSystem.Make

Related

Pointcloud Visualization in Drake Visualizer in Python

I would like to visualize pointcloud in drake-visualizer using python binding.
I imitated how to publish images through lcm from here, and checked out these two issues (14985, 14991). The snippet is as follows :
point_cloud_to_lcm_point_cloud = builder.AddSystem(PointCloudToLcm())
point_cloud_to_lcm_point_cloud.set_name('pointcloud_converter')
builder.Connect(
station.GetOutputPort('camera0_point_cloud'),
point_cloud_to_lcm_point_cloud.get_input_port()
)
point_cloud_lcm_publisher = builder.AddSystem(
LcmPublisherSystem.Make(
channel="DRAKE_POINT_CLOUD_camera0",
lcm_type=lcmt_point_cloud,
lcm=None,
publish_period=0.2,
# use_cpp_serializer=True
)
)
point_cloud_lcm_publisher.set_name('point_cloud_publisher')
builder.Connect(
point_cloud_to_lcm_point_cloud.get_output_port(),
point_cloud_lcm_publisher.get_input_port()
)
However, I got the following runtime error:
RuntimeError: DiagramBuilder::Connect: Mismatched value types while connecting output port lcmt_point_cloud of System pointcloud_converter (type drake::lcmt_point_cloud) to input port lcm_message of System point_cloud_publisher (type drake::pydrake::Object)
When I set 'use_cpp_serializer=True', the error becomes
LcmPublisherSystem.Make(
File "/opt/drake/lib/python3.8/site-packages/pydrake/systems/_lcm_extra.py", line 71, in _make_lcm_publisher
serializer = _Serializer_[lcm_type]()
File "/opt/drake/lib/python3.8/site-packages/pydrake/common/cpp_template.py", line 90, in __getitem__
return self.get_instantiation(param)[0]
File "/opt/drake/lib/python3.8/site-packages/pydrake/common/cpp_template.py", line 159, in get_instantiation
raise RuntimeError("Invalid instantiation: {}".format(
RuntimeError: Invalid instantiation: _Serializer_[lcmt_point_cloud]
I saw the cpp example here, so maybe this issue is specific to python binding.
I also saw this python example, but thought using 'PointCloudToLcm' might be more convenient.
P.S.
I am aware of the development in recent commits on MeshcatVisualizerCpp and MeshcatPointCloudVisualizerCpp, but I am still on the drake-dev stable build 0.35.0-1 and want to stay on drake visualizer until the meshcat c++ is more mature.
The old version in pydrake.systems.meshcat_visualizer.MeshcatVisualizer is a bit too slow on my current use-case (multiple objects drop). I can visualize the pointcloud with this visualization setting, but it took too much machine resources.
Only the message types that are specifically bound in lcm_py_bind_cpp_serializers.cc can be used on an LCM message input/output port connection between C++ and Python. For all other LCM message types, the input/output port connection must be from a Python system to a Python system or a C++ System to a C++ System.
The lcmt_image_array is listed there, but not the lcmt_point_cloud.
If you're stuck using Drake's v0.35.0 capabilities, then I don't see any great solutions. Some options:
(1) Write your own PointCloudToLcm system in Python (by re-working the C++ code into Python, possibly with a narrower set of supported features / channels for simplicity).
(2) Write your own small C++ helper function MakePointCloudPublisherSystem(...) that calls LcmPublisherSystem::Make<lcmt_point_cloud> function in C++, and bind it into Python. Then your Python code can call MakePointCloudPublisherSystem() and successfully connect that to the existing C++ PointCloudToLcm.

How to draw line with Microsoft POS Printer

I am using the Microsoft Point Of Service SDK and I am testing both in my application and the Sample provided with the SDK to try and print a Line with code similar to this:
posPrinter.DrawRuledLine(PrinterStation.Receipt, "0,500", LineDirection.Horizontal, 1, LineStyle.BrokenLine, 1);
I get this error:
POSControlException ErrorCode(Illegal) ExtendedErrorCode(0) occurred: Method DrawRuledLine threw an exception. Attempt was made to perform an illegal or unsupported operation with the device, or an invalid parameter value was used.
Microsoft POS has a tendency to throw very generic errors and I don't know what I am doing wrong. I had similar errors on other methods and it turned out it was because I was passing a parameter that didn't quite work, like a too big a width. But I have tested all kinds of combinations and this always fails. And there is no enough documentation on the parameters it receives.
What parameters do I need to pass to this method to draw a line? Is this the preferred way to draw a line with Microsoft POS?
Microsoft Point Of Service(part of the UnifiedPOS implementation) is an API with an abstract standard specification and does not have all the features of a real printer.
If your printer and the service object that runs it do not have DrawRuledLine functionality, you will get that error.
ErrorCode Enumeration (POS for .NET v1.12 SDK Documentation)
Illegal
An attempt was made to perform an illegal or unsupported operation with the device, or an invalid parameter value was used.
The presence or absence of the function can be confirmed in advance by checking the value of the CapRecRuledLine(CapSlpRuledLine for Slip stations) property.
If you want to draw a line on a receipt with this DrawRuledLine method, you need to switch to a printer and service object that supports that feature.
If you don't want to change the printer, you'll have to replace it with a character line.

xml to xml field attribute transformation using ESQL on message broker compute node

I am new to message broker development. I tried to convert source SOAP over xml file to target SOAP over xml file.On my message flow source message discarded to catch terminal.I am not able to find out the problem
my flow : MQINPUT NODE ---> COMPUTE NODE --> MQOUTPUT NODE
If any provide solution on this that may me helpful for me.
DECLARE soapenv CHARACTER 'SOAP-ENV';
SET OutputRoot.XMNLSC.soapenv:Envelope.soapenv:Body.params.ORIGIN_TYPE_CD = InputRoot.XMNLSC.soapenv:Envelope.soapenv:Body.params.originType;
**
Your first line is definitely wrong, but you should be able to see that from the exceptions you are getting.
The first line should be:
DECLARE soapenv NAMESPACE 'http://schemas.xmlsoap.org/soap/envelope/';
An in the further lines the domain should be XMLNSC not XMNLSC.

How to read the manual page for POSIX refering to error codes?

I am currently working with pthread and read the documentation from here: Pthread Manual Pthread Join.
However, when I read the pages I see the ERRORS, but not the corresponding return values, which will get returned from pthread_join. So my question is, are the ERRORS ordered in ascending order (since it might be an enumerator)?
Error values such as EDEADLK are macros defined by including the <errno.h> header file.
Example:
#include <pthread.h>
#include <errno.h>
...
int retval = pthread_join( threadID, NULL );
if ( retval == EDEADLK )
{
// error-handling code for deadlock
}
else if ( retval == EINVAL )
{
// error-handling code for invalid thread id
}
else if ( retval == ESRCH )
{
// error-handling code for no such thread id
}
Note that the above code is correct only for Linux, as the only error number specified by POSIX for pthread_join() is EDEADLCK.
Per the POSIX standard for error numbers, (bolded portions particularly relevant to your question):
2.3 Error Numbers
Most functions can provide an error number. The means by which each
function provides its error numbers is specified in its description.
Some functions provide the error number in a variable accessed through
the symbol errno, defined by including the <errno.h> header.
The value of errno should only be examined when it is indicated to
be valid by a function's return value. No function in this volume of
POSIX.1-2008 shall set errno to zero. For each thread of a process,
the value of errno shall not be affected by function calls or
assignments to errno by other threads.
Some functions return an error number directly as the function value. These functions return a value of zero to indicate success.
If more than one error occurs in processing a function call, any one
of the possible errors may be returned, as the order of detection is
undefined.
Implementations may support additional errors not included in this
list, may generate errors included in this list under circumstances
other than those described here, or may contain extensions or
limitations that prevent some errors from occurring.
The ERRORS section on each reference page specifies which error
conditions shall be detected by all implementations ("shall fail") and
which may be optionally detected by an implementation ("may fail"). If
no error condition is detected, the action requested shall be
successful. If an error condition is detected, the action requested
may have been partially performed, unless otherwise stated.
Implementations may generate error numbers listed here under
circumstances other than those described, if and only if all those
error conditions can always be treated identically to the error
conditions as described in this volume of POSIX.1-2008.
Implementations shall not generate a different error number from one
required by this volume of POSIX.1-2008 for an error condition
described in this volume of POSIX.1-2008, but may generate additional
errors unless explicitly disallowed for a particular function.
Each implementation shall document, in the conformance document,
situations in which each of the optional conditions defined in
POSIX.1-2008 is detected. The conformance document may also contain
statements that one or more of the optional error conditions are not
detected.
Certain threads-related functions are not allowed to return an error
code of [EINTR]. Where this applies it is stated in the ERRORS section
on the individual function pages.
The following macro names identify the possible error numbers, in the context of the functions specifically defined in this volume of
POSIX.1-2008; these general descriptions are more precisely defined in
the ERRORS sections of the functions that return them. Only these
macro names should be used in programs, since the actual value of the
error number is unspecified. All values listed in this section shall
be unique, except as noted below. The values for all these macros
shall be found in the <errno.h> header defined in the Base
Definitions volume of POSIX.1-2008. The actual values are unspecified
by this volume of POSIX.1-2008.
[E2BIG]
Argument list too long. The sum of the number of bytes
used by the new process image's argument list and environment
list is greater than the system-imposed limit of {ARG_MAX} bytes.
or:
Lack of space in an output buffer.
or:
Argument is greater than the system-imposed maximum.
[EACCES]
Permission denied. An attempt was made to access a file
in a way forbidden by its file access permissions.
[EADDRINUSE]
Address in use. The specified address is in use.
[EADDRNOTAVAIL]
Address not available. The specified address is not
available from the local system.
[EAFNOSUPPORT]
Address family not supported. The implementation does
not support the specified address family, or the specified
address is not a valid address for the address family
of the specified socket.
[EAGAIN]
Resource temporarily unavailable. This is a temporary
condition and later calls to the same routine may complete
normally.
[EALREADY]
Connection already in progress. A connection request is already
in progress for the specified socket.
.
.
.

change trace log format in emqtt message broker

I am using emqtt message broker for mqtt.
I am not a erlang developer and has zero knowledge on that.
I have used this erlang based broker, because after searching many open source broker online and suggestions from people about the advantage of erlang based server.
Now i am kind of stuck with the out put of the emqttd_cli trace command.
Its not json type and if i use a perl parser to convert to json type i am getting delayed output.
I want to know, in which file i could change the trace log output format.
I looked on the trace code of the broker and found a file src/emqttd_protocol.erl. An exported function named trace/3 has the code that you need.
Second argument of this function, named Packet, has the information of receive & send data via broker. You can fetch required data from it and format according to how you want to print.
Edit : Sample modified code added
trace(recv, Packet, ProtoState) ->
PacketHeader = Packet#mqtt_packet.header,
HostInfo = esockd_net:format(ProtoState#proto_state.peername),
%% PacketInfo = {ClientId, Username, ClientIP, ClientPort, Payload, QoS, Retain}
PacketInfo = {ProtoState#proto_state.client_id, ProtoState#proto_state.username, lists:nth(1, HostInfo), lists:nth(3, HostInfo), Packet#mqtt_packet.payload, PacketHeader#mqtt_packet_header.qos, PacketHeader#mqtt_packet_header.retain},
?LOG(info, "Data Received ~s", [PacketInfo], ProtoState);

Resources