Giter VIP home page Giter VIP logo

pprzlink's Introduction

PPRZLINK

PPRZLINK is a messages toolkit (message definition, code generators, libraries) to be used with Paparazzi UAV System and compatible systems. One tool that uses PPRZLINK is the Flying Robot Commander, a web based, RESTful application for controlling multiple aircraft.

Documentation

Documentation is in the doc subdirectory and can be viewed on https://pprzlink.readthedocs.org

To build the docs locally:

sudo pip install sphinx sphinx-autobuild sphinx_rtd_theme
cd doc && make html

Libraries

PPRZLINK libraries are available for the following programming languages:

License

PPRZLINK is released under:

  • GPLv2 (or later) for the OCaml and C libraries (v1.0 and v2.0)
  • GPLv3 (or later) for the code generators
  • LGPLv3 (or later) for the Python library (v1.0 and v2.0)

See license files (LICENSE.xxxx) for details

Messages

Messages are defined in the messages.xml file and are grouped into the following message classes:

  • telemetry
  • datalink
  • ground
  • alert
  • intermcu

Please reference Paparazzi Messages Document for a more detailed overview.

Message Classes

Telemetry

Telemetry messages are sent from the aircraft to the ground and are defined in the telemetry class of the messages.xml file.

Datalink

Datalink messages are sent from the ground to the aircraft and are defined in the datalink class of the messages.xml file.

Ground

Ground messages are sent to the ground network agents (GCS, server, link, etc) and are defined in the ground class of the messages.xml file.

Alert

TBD

InterMCU

TBD

Python Library

The Python PPRZLINK ivy interface is defined in ivy.py. There is also a serial version of the interface in serial.py.

Ivy Message Call Sequence

Add library root to the search path:

# if PAPARAZZI_SRC not set, then assume the tree containing this file is a reasonable substitute
PPRZ_SRC = getenv("PAPARAZZI_SRC", path.normpath(path.join(path.dirname(path.abspath(__file__)), '~/paparazzi/')))

sys.path.append(PPRZ_SRC + "/sw/ext/pprzlink/lib/v1.0/python")

from pprzlink.ivy  import IvyMessagesInterface
from pprzlink.message   import PprzMessage
...

Create a new IvyMessagesInterface instance:

ivy_interface = IvyMessagesInterface("FlyingRobotCommander", start_ivy=False)

Subscribe to all messages:

ivy_interface.subscribe(callback_aircraft_messages)
...

Start the interface:

ivy_interface.start()
...

Send messages:

# Main Loop
ivy_interface.send(msg)
ivy_interface.send_raw_datalink(msg)
...

Stop the interface in the end:

ivy_interface.shutdown()
...

Ivy Message Construction

It's easy to construct messages to send over the ivy message bus. Here are a few example python functions for reference.

Datalink Message

def guidance(ac_id, flag, x, y, z, yaw):
    msg = PprzMessage("datalink", "GUIDED_SETPOINT_NED")
    msg['ac_id'] = ac_id
    msg['flags'] = flag
    msg['x']     = x
    msg['y']     = y
    msg['z']     = z
    msg['yaw']   = yaw

    ivy_interface.send_raw_datalink(msg)

Ground Message

def flightblock(ac_id, fb_id):
    msg = PprzMessage("ground", "JUMP_TO_BLOCK")
    msg['ac_id']    = ac_id
    msg['block_id'] = fb_id

    ivy_interface.send(msg)

Data Request Message

    def request_config(ac_id):
        def aircraft_config_callback(ac_id, msg):
            logger.info(f"Got new aircraft config {ac_id}: {msg}")
            name = msg['ac_name']
            ....
            
        ivy.send_request(
            class_name="ground",
            request_name="CONFIG",
            callback=aircraft_config_callback,
            ac_id=ac_id
        )

Subscribing to Ivy Messages

Subscribe method can be used to register a callback for all messages:

def cb(ac_id: str, msg: PprzMessage):
    # Subscribed to all messages without any filter
    pass
binding_id = ivy.subscribe(cb)

or to receive messages of a certain class:

def notify_new_aircraft(ac_id: str, msg: PprzMessage):
    assert msg.class_name == 'ground'
    assert msg.name == 'NEW_AIRCRAFT'
    
binding_id = ivy.subscribe(notify_new_aircraft, PprzMessage("ground", "NEW_AIRCRAFT"))

or you can have a custom regex to catch certain messages:

def answer_request(ac_id: str, message: PprzMessage):
    pass

binding_id = ivy.subscribe(answer_request, r"^((\S*\s*)\d+_\d+ CONFIG_REQ( .*|$))")

Please note that the regex should match the whole message as one group. It means you probably need catch all patterns in the beginning and end, also if there are parentheses within your custom pattern, you should wrap the whole pattern in parentheses. Note that the message can have trailing spaces which should be kept to properly parse the message into a PprzMessage object down the line.

subscribe method returns an id which can later be used to remove that subscription. See send_request implementation in ivy.py for a practical example.

ivy.unsubscribe(binding_id)
# or
ivy.unbind(binding_id)

If your agent needs to answer advanced request messages you can use subscribe_request_answerer method. The callback you register should return a PprzMessage which will be used as the response.

def answer_request(ac_id: int, request_msg: PprzMessage) -> PprzMessage:
    # request_msg will be of type CONFIG_REQ
    
    answer = PprzMessage("ground", "CONFIG")
    answer['ac_id'] = request_msg['ac_id']
    answer['flight_plan'] = 'file:///path/to/fligh_plan.xml'
    answer[...] = ...

    return answer 

ivy.subscribe_request_answerer(answer_request, "CONFIG")  # No `_REQ` here

C standalone Library

The C standalone library can be used when only a few messages using the PPRZ transport are expected (in comparison with the full C library where all messages are generated and both device and transport can be selected independently). This is useful when implementing a program in C in an embedded computer talking to the autopilot through a serial port. It is a header only library, so there is no file to compile.

Generation of a C standalone messages parse

Assuming we only need the GPS and ATTITUDE messages, either sending or receiving, the generation of the library is as follow:

./tools/generator/gen_messages.py --protocol 2.0 --lang C_standalone -o build/pprzlink/my_pprz_messages.h message_definitions/v1.0/messages.xml telemetry --opt ATTITUDE,GPS

The generated files will be placed in the folder build/pprzlink in this case. The folder pprzlink and the files it contains should be copied to your project directory (or any library folder part of your include paths).

Usage for sending

Sending a message is done as follows:

Include the library header

#include "pprzlink/my_pprz_messages.h"

Implement some required callbacks (definitions can be found in pprzlink/pprzlink_standalone.h): check_space, put_char, send_message (or NULL if not needed)

int check_space(uint8_t n) {
  // implement your check space function here
}

void put_char(uint8_t c) {
  // implement your put char function here
}

void send_message(void) {
  // implement your send message function here
}

Init the TX structure (definitions can be found in pprzlink/pprzlink_standalone.h):

// somewhere in your init section
struct pprzlink_device_tx dev_tx = pprzlink_device_tx_init(check_space, put_char, send_message /* or NULL */);

Send messages (replace ... with paramters, see definition in pprzlink/my_pprz_messages.h):

// in the case of GPS message
pprzlink_msg_send_GPS(&dev_tx, ...);

Usage for receiving

Include the library header

#include "pprzlink/my_pprz_messages.h"

Implement some required callbacks (definitions can be found in pprzlink/pprzlink_standalone.h): char_available, get_char, new_message as well as a buffer large enough to receive your messages (max 255 bytes):

int char_available(void) {
  // implement your char available function here
}

uint8_t get_char(void) {
  // implement your get char function here
}

uint8_t rx_buffer[255];

void new_message(uint8_t sender_id, uint8_t receiver_id, uint8_t class_id, uint8_t message_id, uint8_t *buf, void *user_data) {
  // check message/class IDs to before extracting data from the messages
  if (message_id == PPRZ_MSG_ID_GPS) {
    // get data from GPS
    int32_t east = pprzlink_get_GPS_utm_east(buf);
    int32_t north = pprzlink_get_GPS_utm_north(buf);
  }
  else if (message_id == PPRZ_MSG_ID_ATTITUDE) {
    // get data from ATTITUDE
  }
}

Init the RX structure (definitions can be found in pprzlink/pprzlink_standalone.h):

// somewhere in your init section
struct pprzlink_device_rx dev_rx = pprzlink_device_rx_init(char_available, get_char, rx_buffer, (void *)&user_data);

Where user_data is a pointer to a structure that you may want to pass at init and use in the new_message callback. If no user data are needed, just pass NULL as argument value. Parse messages by calling this function in your mainloop:

pprzlink_check_and_parse(&dev_rx, new_message);

pprzlink's People

Contributors

amtcvx avatar bartslinger avatar coppolam avatar deonblaauw avatar dewagter avatar ewoudsmeur avatar fabien-b avatar flixr avatar fvantienen avatar gautierhattenberger avatar guidoai avatar hooperfly avatar jburns11 avatar joostmeulenbeld avatar kevindehecker avatar kirkscheper avatar matteobarbera avatar mavlab-field avatar mjafarmashhadi avatar noether avatar pcampolucci avatar podhrmic avatar rijesha avatar rmeertens avatar titusbraber avatar tmldeponti avatar tomvand avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pprzlink's Issues

Bitmask

It would be nice if we could have a bitmask option next to the values option. For simplest implementation it can be made the same, except each value is shifted with the position in the array. This could make it easier to understand messages values like INS_EKF2: control_mode if the messages.ml can parse it.

I'm not 100% sure how to implement this correctly in the paparazzi project messages.ml that is why I made this issue.

Error: class_name ground not found

Running a python script from Paparazzi (gvfFormation.py), ivy? is printing these errors all the time:

Error: class_name ground not found
Error: class_name alert not found

Gautier suggested to add an id to those clases without one at var/messages.xml . This fix (apparently) stopped the problem.

ENH: Adding python decorators for subscribing to messages

I'm working on a project which I'm using pprzlink in. I created a couple of decorator classes for subscribing to messages and I was wondering if they are a good addition to pprzlink.

There is IvySubscribe that will bind the function to a list of message types:

# To one message type
@IvySubscribe(ivy_link=ivy, message_types=[("ground", "NEW_AIRCRAFT")])
def new_aircraft_callback(ac_id, msg):
    pass

# RegEx is also supported
@IvySubscribe(ivy_link=ivy, message_types=["(.*)")])
def new_aircraft_callback(ac_id, msg):
    pass

# Subscribe to all 
@IvySubscribe(ivy_link=ivy)
def get_all_messages(ac_id, msg):
    pass

I created IvySubscribeOnce that stop listening for that type of message as soon as it receives one (useful for the new request messages):


@IvySubscribeOnce(
    ivy_link=ivy_link,
    message_types=[r"^((\S*\s*)?\d+_\d+ ground %s_REQ( .*|$))" % request_name]
)
def request_callback(ac_id, msg):
    pass

And if you needed to unbind manually you can use get_all_messages.__ivy_subs__.unsubscribe().

They are useful in my project, but whether it's a good idea to have them as a part of pprz_link itself, I don't know. What do you think?

Cleanup messages

We currently only have 6 messages free which is not that much anymore. I think it would be nice if we could cleanup some of the old/unused messages to avoid extending the ID at first.

Maybe later on we could extend the ID with a class like others also have, but for now I think it is best to just cleanup the not used messages.

MISSION_GOTO_WP_LLA altitude unit mismatch

Just leaving this here because I don't know where the fix would go: The MISSION_GOTO_WP_LLA message is described as having a wp_alt field containing altitude in millimeters. When trying the mission module with v5.12_stable, the module actually interprets the value as meters.

Ensure correct endianness for pprzlink

Based on my talk with @gautierhattenberger

pprzlink uses the host byte order, which is typically little endian for most autopilots. Conveniently, most computers are little-endian these days, so it works out. However, it would be good to ensure that the byte order is the same for both parties, or even better switch to network byte order for pprzlink to make this universal.

Possible solution: add hton*()/ntoh*() shims to the generated code.

I might get to this later in the year, hence assigning to myself.

Pprzlog maximum time overflow

We take the time in usec like this:
extern void pprzlog_transport_init(struct pprzlog_transport *t, uint32_t (*get_time_usec_t)(void));
But here it gets divided by 100: https://github.com/paparazzi/pprzlink/blob/master/lib/v2.0/C/pprzlog_transport.c#L92

This means that the maximum time in usec is 2^32/1e6 = 4294 seconds / 60 = 71,58 minutes. While theoretically we could fit 2^32/1e4 = 429496 seconds / 60 = 7158 minutes = 119 hours.

We should change the get_time_usec_t to get_time_10msec_t or to 64bits.

Add API to attach multiple transports/parsers to a link

Currently one normally uses the <transport>_check_and_parse functions to - well - check if there are new input chars on the device and if yes parse them using the transport.

It would be good to have the possibility to easily attach multiple transports/parsers to a link and pass the incoming data to all of them.

See also #10

Adding a new message?

Hi
I am not sure if this is an issue but i would love to add a new message about my airborne Yagi antenna

<message name="AIRBORNE_ANTENNA" id="181">
  <field name="mag_heading_deg"   type="float"/>
  <field name="gps_heading_deg"  type="float"/>
  <field name="ant_azimuth_deg" type="float"/>
  <field name="ant_elevation_deg" type="float"/>
</message>

The message can be different i just used the above code as an example.
Basically i can't find a message to transmit the mag Heading in degrees without interfering with other modules plus that there is no message for the airborne antenna.
Chris

HITL doesn't work with Ppprzlink 2.0

The issue is apparently memory alignment,

From nps_main_hitl.c when parsing DL_COMMANDS:

Pprzlink 1.0

  • everything works fine
#define DL_COMMANDS_values_length(_payload) _PPRZ_VAL_len_aligned(_payload, 2)
#define DL_COMMANDS_values(_payload) _PPRZ_VAL_int16_t_array(_payload, 3)

Pprzlink 2.0

  • length is at index 4, and payload is at index 5
/** Getter for length of array values in message COMMANDS
 *
 * @return values : 
 */
 static inline uint8_t pprzlink_get_COMMANDS_values_length(__attribute__ ((unused)) void* _payload) {
    return _PPRZ_VAL_len_aligned(_payload, 4);
}

/** Getter for field values in message COMMANDS
  *
  * @param _payload : a pointer to the COMMANDS message
  * @return 
  */
static inline int16_t * pprzlink_get_DL_COMMANDS_values(uint8_t * _payload __attribute__((unused)))
{
    return _PPRZ_VAL_int16_t_array(_payload, 5);
}


/* Compatibility macros */
#define DL_COMMANDS_values_length(_payload) pprzlink_get_COMMANDS_values_length(_payload)
#define DL_COMMANDS_values(_payload) pprzlink_get_DL_COMMANDS_values(_payload)
  • length is returned properly, but instead of a pointer to the payload I am getting NULL (DL_COMMANDS_values(buf) = NULL) and as a result memcopy crashes (access to memory at NULL).
printf("DL_COMMANDS_values_length(buf) = %u\n",DL_COMMANDS_values_length(buf));
printf("DL_COMMANDS_values(buf) = %p\n",DL_COMMANDS_values(buf));

prints

DL_COMMANDS_values_length(buf) = 5
DL_COMMANDS_values(buf) = (nil)

while the buffer values are:

9,0,1,102,5,0,0,0,0,0,0,0,0,0,0

(sender id =9, dest_id=0, class=telemetry, msg_id=102)

When turning the alignment off, the same result is produced.

@gautierhattenberger what do you think?

Allow encrypted and unencrypted messages on the same link

Use cases

  1. we want to have encrypted communication, as described in Messages Format but we want to be able to process unencrypted "management" messages (such as request to renegotiate encryption keys or some routing info). These unencrypted messages are validated in a different way (context based, signed, etc)
  2. in multi-uav case, we want to be able to communicate with unencrypted nodes (for interoperability reasons).

In both cases, we need to somehow distinguish between encrypted and unencrypted messages (because the length and decoding is different).

Options

We have these option:

A. Different STX byte for plaintext and encrypted messages

Pros:

  • simple
  • no additional bytes

Cons:

  • increasing likelihood of incorrectly decoded messages

B. Adding a byte with crypto/plaintext flag

NOTE: this byte would still be authenticated so it cannot be tampered with!
Pros:

  • still simple
  • can flag different encryption methods (theoretically can support multiple encrypted links)

Cons:

  • additional overhead
  • not backwards compatible:-(

C. Using an existing byte

Note: not really an option, because only Pprzlink 2.0 has extra CLASS/COMPONENT byte, but if we use a bit from this byte then the whole byte would have to be unencrypted (perhaps revealing too much about the message).

Summary

I am in favor of solution A as it is backwards compatible and doesn't increase overhead. Thoughts? @gautierhattenberger @flixr

Pprzlink version byte

Currently, there is no way to determine which Pprzlink version a given message has, so all nodes in the network have to know in advance which version should be used (1 or 2).

Adding a byte (it can be as simple as a different STX byte for Pprzlink 2.0) it would be possible to auto-detect the pprzlink version.

Indeed this is a significant change, so perhaps it can be made optional (like AUTODETECT_PPRZLINK_VERSION=true/false). Easy to implement on GCS side, harder on autopilot side.

This came as a feature request from one user.

What do you think @gautierhattenberger ?

Change license to LGPL

Changing the license of PPRZLINK to LGPL (with proper exceptions for static linking https://en.wikipedia.org/wiki/GPL_linking_exception) would make integration into non-GPL code easier.

Below is a list (maybe not complete yet) of contributors extracted from git + file headers, for the current pprzlink repository and also from the former code previously integrated to Paparazzi (paparazzi/paparazzi@22ca426 and before)

#### PAPARAZZI ####
git ls-tree -r -z --name-only HEAD -- conf/messages.* conf/units.xml sw/tools/generators/gen_messages.ml sw/airborne/subsystems/datalink/*transport* sw/airborne/subsystems/datalink/xbee* sw/airborne/subsystems/datalink/uart_print.h sw/lib/python/**/* sw/lib/ocaml/pprz.ml* sw/lib/ocaml/xbee.ml* sw/lib/ocaml/serial.ml* sw/lib/ocaml/logpprz.ml* sw/lib/ocaml/convert.c | xargs -0 -n1 git blame --line-porcelain HEAD |grep  "^author "|sort|uniq -c|sort -nr 
   3591 author Felix Ruess
   1882 author Gautier Hattenberger
   1718 author Pascal Brisset
   1169 author Antoine Drouin
    218 author Martin Mueller
    217 author Allen Ibara
    129 author Christophe De Wagter
     82 author Freek van Tienen
     61 author John Stowers
     27 author podhrmic
     27 author Cameron Lee
     26 author Oswald Berthold
     20 author Ewoud Smeur
     16 author dewagter
     15 author fvantienen
     12 author kirkscheper
     11 author Bruzzlee
      9 author Loic Drumettaz
      9 author Allen
      6 author Stephen Dwyer
      5 author Tobias Muench
      5 author LodewijkSikkel
      5 author agressiva
      4 author Pranay Sinha
      4 author karlito139
      3 author Paul Cox
      3 author guidoAI
      2 author Roland Meertens
      2 author rad
      2 author [email protected]
      2 author Christoph Niemann
      1 author OSAM-UAV Team
      1 author Louis Dugrain
      1 author Eric Parsonage

grep "Copyright" conf/messages.* conf/units.xml sw/tools/generators/gen_messages.ml sw/airborne/subsystems/datalink/*transport* sw/airborne/subsystems/datalink/xbee* sw/airborne/subsystems/datalink/uart_print.h sw/lib/python/**/* sw/lib/ocaml/pprz.ml* sw/lib/ocaml/xbee.ml* sw/lib/ocaml/serial.ml* sw/lib/ocaml/logpprz.ml* sw/lib/ocaml/convert.c 
sw/tools/generators/gen_messages.ml: * Copyright (C) 2003-2008 ENAC, Pascal Brisset, Antoine Drouin
sw/airborne/subsystems/datalink/downlink_transport.h: * Copyright (C) 2003-2010 The Paparazzi Team
sw/airborne/subsystems/datalink/ivy_transport.c: * Copyright (C) 2003  Pascal Brisset, Antoine Drouin
sw/airborne/subsystems/datalink/ivy_transport.c: * Copyright (C) 2014  Gautier Hattenberger <[email protected]>
sw/airborne/subsystems/datalink/ivy_transport.h: * Copyright (C) 2003  Pascal Brisset, Antoine Drouin
sw/airborne/subsystems/datalink/ivy_transport.h: * Copyright (C) 2014  Gautier Hattenberger <[email protected]>
sw/airborne/subsystems/datalink/pprzlog_transport.c: * Copyright (C) 2014 Gautier Hattenberger <[email protected]>
sw/airborne/subsystems/datalink/pprzlog_transport.h: * Copyright (C) 2014 Gautier Hattenberger <[email protected]>
sw/airborne/subsystems/datalink/pprz_transport.c: * Copyright (C) 2006  Pascal Brisset, Antoine Drouin
sw/airborne/subsystems/datalink/pprz_transport.c: * Copyright (C) 2014  Gautier Hattenberger <[email protected]>
sw/airborne/subsystems/datalink/pprz_transport.h: * Copyright (C) 2003  Pascal Brisset, Antoine Drouin
sw/airborne/subsystems/datalink/pprz_transport.h: * Copyright (C) 2014  Gautier Hattenberger <[email protected]>
sw/airborne/subsystems/datalink/transport.h: * Copyright (C) 2011-2014 Gautier Hattenberger <[email protected]>
sw/airborne/subsystems/datalink/xbee24.h: * Copyright (C) 2009  ENAC, Pascal Brisset
sw/airborne/subsystems/datalink/xbee24.h: * Copyright (C) 2014  Gautier Hattenberger <[email protected]>
sw/airborne/subsystems/datalink/xbee868.h: * Copyright (C) 2009  ENAC, Pascal Brisset
sw/airborne/subsystems/datalink/xbee868.h: * Copyright (C) 2014  Gautier Hattenberger <[email protected]>
sw/airborne/subsystems/datalink/xbee.c: * Copyright (C) 2006  Pascal Brisset, Antoine Drouin
sw/airborne/subsystems/datalink/xbee.c: * Copyright (C) 2014  Gautier Hattenberger <[email protected]>
sw/airborne/subsystems/datalink/xbee.h: * Copyright (C) 2006  Pascal Brisset, Antoine Drouin
sw/airborne/subsystems/datalink/xbee.h: * Copyright (C) 2014  Gautier Hattenberger <[email protected]>
sw/airborne/subsystems/datalink/uart_print.h: * Copyright (C) 2005 Pascal Brisset, Antoine Drouin
sw/airborne/subsystems/datalink/uart_print.h: * Copyright (C) 2015 Gautier Hattenberger <[email protected]>
sw/lib/ocaml/pprz.ml: * Copyright (C) 2003 Pascal Brisset, Antoine Drouin
sw/lib/ocaml/pprz.mli: * Copyright (C) 2003 Pascal Brisset, Antoine Drouin
sw/lib/ocaml/xbee.ml: * Copyright (C) 2006 ENAC, Pascal Brisset, Antoine Drouin
sw/lib/ocaml/xbee.mli: * Copyright (C) 2006 ENAC, Pascal Brisset, Antoine Drouin
sw/lib/ocaml/serial.ml: * Copyright (C) 2004 CENA/ENAC, Pascal Brisset
sw/lib/ocaml/serial.mli: * Copyright (C) 2004 CENA/ENAC, Pascal Brisset
sw/lib/ocaml/logpprz.ml: * Copyright (C) 2003 Pascal Brisset, Antoine Drouin
sw/lib/ocaml/convert.c:   Copyright (C) 2004 Pascal Brisset, Antoine Drouin

#### PPRZLINK ####

git ls-tree -r -z --name-only HEAD -- **/* | xargs -0 -n1 git blame --line-porcelain HEAD |grep  "^author "|sort|uniq -c|sort -nr 
  10923 author Felix Ruess
   8295 author Gautier Hattenberger
    246 author Rijesh Augustine
     82 author HooperFly
     65 author kevindehecker
     50 author kirkscheper
     41 author Christophe De Wagter
     11 author Ewoud Smeur
      9 author Roland Meertens
      9 author guidoAI

Main contributors are well known and easy to reach. What about minor ones, former student and so on. Do we set a limit and where ?

IvyMessagesInterface send_request not working as expected

The function IvyMessagesInterface.send_request is sending the agent name in the place of the message class.

A CONFIG request message is sent as IvyMessagesInterface 63240_1 CONFIG_REQ 200 instead of ground 63240_1 CONFIG_REQ 200

self.agent_name, new_id, request_message.name, request_message.payload_to_ivy_string()

should be replaced by

class_name, new_id, request_message.name, request_message.payload_to_ivy_string()

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.