From c5d7c29fd1bf4688676d3198501b2d74a8e78771 Mon Sep 17 00:00:00 2001 From: Josh Glazer Date: Mon, 10 Feb 2020 17:25:22 -0500 Subject: [PATCH 01/11] [#211] Add js logging functions --- .../static/js/roslibjs/ros-helpers.js | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/robot/basestation/static/js/roslibjs/ros-helpers.js b/robot/basestation/static/js/roslibjs/ros-helpers.js index 5d0f746d8..205cfa9fa 100644 --- a/robot/basestation/static/js/roslibjs/ros-helpers.js +++ b/robot/basestation/static/js/roslibjs/ros-helpers.js @@ -2,6 +2,13 @@ REQUEST_TIMEOUT = 3000 ROTATE_TIMEOUT = 1000 lastRotate = 0 +// ROS logging severity level constants +const ROSDEBUG = 1 // debug level +const ROSINFO = 2 // general level +const ROSWARN = 4 // warning level +const ROSERROR = 8 // error level +const ROSFATAL = 16 // fatal/critical level + function initRosWeb () { ros = new ROSLIB.Ros({ url: 'ws://' + env.HOST_IP + ':9090' @@ -20,6 +27,15 @@ function initRosWeb () { appendToConsole('Connection to websocket server closed.') }) + /* Logging */ + + // publishes log messages to /rosout + ros_logger = new ROSLIB.Topic({ + ros: ros, + name: 'rosout', + messageType: 'rosgraph_msgs/Log' + }) + /* general controls */ // setup a client for the ping service @@ -188,6 +204,72 @@ function initRosWeb () { } /* functions used in main code */ +function logGeneric (logLevel, message) { + // next 3 lines taken from roslibjs action server example + let currentTime = new Date() + let secs = Math.floor(currentTime.getTime()/1000) + let nsecs = Math.round(1000000000*(currentTime.getTime()/1000-secs)) + + ros_logger.publish( + new ROSLIB.Message({ + header : { + // uint32 seq // sequence ID: consecutively increasing ID // seems to be automatic? + stamp : { + secs : secs, + nsecs : nsecs + } + // string frame_id // Frame this data is associated with // not relevant? + }, + level : logLevel, + // string name # name of the node + msg : message + // string file # file the message came from + // string function # function the message came from + // uint32 line # line the message came from + // string[] topics # topic names that the node publishes + }) + ) +} + +// Copying how rospy handles the logging functions: +// All log messages should go to the log file (but how?) +// debug messages only go to /rosout if a value is set while initializing the js +// info goes to stdout, warn-error-fatal go to stderr +// rospy also takes in *args and **kwargs, how does this work and do I need to implement that? +function logDebug (message) { + // @TODO only log debug messages if we set a parameter somewhere. + // in rospy this parameter is set when you initialize your node + // with: rospy.init_node(nodeName, log_level=rospy.DEBUG) + // for the webpage maybe we can set it when we run initRosWeb() + logGeneric(ROSDEBUG, message) +} +// @TODO console should output: "[level] [timestamp]: message" +// where do I get the timestamp from? maybe put the logging inside logGeneric() +function logInfo (message) { + consoleMsg = "[INFO] " + ': ' + message + console.error(consoleMsg) + appendToConsole(consoleMsg) + logGeneric(ROSINFO, message) +} +function logWarn (message) { + consoleMsg = "[WARN] " + ': ' + message + console.error(consoleMsg) + appendToConsole(consoleMsg) + logGeneric(ROSWARN, message) +} +function logErr (message) { + consoleMsg = "[ERROR] " + ': ' + message + console.error(consoleMsg) + appendToConsole(consoleMsg) + logGeneric(ROSERROR, message) +} +function logFatal (message) { + consoleMsg = "[FATAL] " + ': ' + message + console.error(consoleMsg) + appendToConsole(consoleMsg) + logGeneric(ROSFATAL, message) +} + function requestMuxChannel (elemID, callback, timeout = REQUEST_TIMEOUT) { let dev = elemID[elemID.length - 1] let request = new ROSLIB.ServiceRequest({ device: dev }) From eae61725be3b6d8611d2c2e0509f647c0042c3a5 Mon Sep 17 00:00:00 2001 From: Josh Glazer Date: Mon, 10 Feb 2020 18:56:34 -0500 Subject: [PATCH 02/11] [#211] Add timestamps to log messages --- .../static/js/roslibjs/ros-helpers.js | 56 ++++++++++++------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/robot/basestation/static/js/roslibjs/ros-helpers.js b/robot/basestation/static/js/roslibjs/ros-helpers.js index 205cfa9fa..6b88f98ae 100644 --- a/robot/basestation/static/js/roslibjs/ros-helpers.js +++ b/robot/basestation/static/js/roslibjs/ros-helpers.js @@ -204,20 +204,52 @@ function initRosWeb () { } /* functions used in main code */ -function logGeneric (logLevel, message) { + +function getTimestamp () { // next 3 lines taken from roslibjs action server example let currentTime = new Date() let secs = Math.floor(currentTime.getTime()/1000) let nsecs = Math.round(1000000000*(currentTime.getTime()/1000-secs)) + return {secs : secs, nsecs : nsecs} +} + +function logGeneric (logLevel, message) { + timestamp = getTimestamp() + timeVal = timestamp.secs + timestamp.nsecs/10e8 + timeVal = timeVal.toFixed(3) + + switch (logLevel) { + case ROSDEBUG: + break + case ROSINFO: + //floor(timestamp.nsecs/1000, 2) + consoleMsg = "[INFO] " + '[' + timeVal + ']' + ': ' + message + console.log(consoleMsg) + appendToConsole(consoleMsg, false) + break + case ROSWARN: + consoleMsg = "[WARN] " + '[' + timeVal + ']' + ': ' + message + console.error(consoleMsg) + appendToConsole(consoleMsg, false) + break + case ROSERR: + consoleMsg = "[ERROR] " + '[' + timeVal + ']' + ': ' + message + console.error(consoleMsg) + appendToConsole(consoleMsg, false) + break + case ROSFATAL: + consoleMsg = "[FATAL] " + '[' + timeVal + ']' + ': ' + message + console.error(consoleMsg) + appendToConsole(consoleMsg, false) + break + } + ros_logger.publish( new ROSLIB.Message({ header : { // uint32 seq // sequence ID: consecutively increasing ID // seems to be automatic? - stamp : { - secs : secs, - nsecs : nsecs - } + stamp : timestamp // string frame_id // Frame this data is associated with // not relevant? }, level : logLevel, @@ -243,30 +275,16 @@ function logDebug (message) { // for the webpage maybe we can set it when we run initRosWeb() logGeneric(ROSDEBUG, message) } -// @TODO console should output: "[level] [timestamp]: message" -// where do I get the timestamp from? maybe put the logging inside logGeneric() function logInfo (message) { - consoleMsg = "[INFO] " + ': ' + message - console.error(consoleMsg) - appendToConsole(consoleMsg) logGeneric(ROSINFO, message) } function logWarn (message) { - consoleMsg = "[WARN] " + ': ' + message - console.error(consoleMsg) - appendToConsole(consoleMsg) logGeneric(ROSWARN, message) } function logErr (message) { - consoleMsg = "[ERROR] " + ': ' + message - console.error(consoleMsg) - appendToConsole(consoleMsg) logGeneric(ROSERROR, message) } function logFatal (message) { - consoleMsg = "[FATAL] " + ': ' + message - console.error(consoleMsg) - appendToConsole(consoleMsg) logGeneric(ROSFATAL, message) } From 3e7b2c5ac72661a7e965ba8c36027fb14f14c49b Mon Sep 17 00:00:00 2001 From: Josh Glazer Date: Mon, 10 Feb 2020 19:07:37 -0500 Subject: [PATCH 03/11] [#211] Fix typo --- robot/basestation/static/js/roslibjs/ros-helpers.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/robot/basestation/static/js/roslibjs/ros-helpers.js b/robot/basestation/static/js/roslibjs/ros-helpers.js index 6b88f98ae..39133d0f0 100644 --- a/robot/basestation/static/js/roslibjs/ros-helpers.js +++ b/robot/basestation/static/js/roslibjs/ros-helpers.js @@ -233,7 +233,7 @@ function logGeneric (logLevel, message) { console.error(consoleMsg) appendToConsole(consoleMsg, false) break - case ROSERR: + case ROSERROR: consoleMsg = "[ERROR] " + '[' + timeVal + ']' + ': ' + message console.error(consoleMsg) appendToConsole(consoleMsg, false) @@ -244,7 +244,7 @@ function logGeneric (logLevel, message) { appendToConsole(consoleMsg, false) break } - + ros_logger.publish( new ROSLIB.Message({ header : { From 31bc68b1a76687f05933c0b92da59fb50839d6bc Mon Sep 17 00:00:00 2001 From: Josh Glazer Date: Mon, 10 Feb 2020 21:47:37 -0500 Subject: [PATCH 04/11] [#211] Refactor timestamp calculations --- .../static/js/roslibjs/ros-helpers.js | 41 ++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/robot/basestation/static/js/roslibjs/ros-helpers.js b/robot/basestation/static/js/roslibjs/ros-helpers.js index 39133d0f0..9c83628d9 100644 --- a/robot/basestation/static/js/roslibjs/ros-helpers.js +++ b/robot/basestation/static/js/roslibjs/ros-helpers.js @@ -206,40 +206,42 @@ function initRosWeb () { /* functions used in main code */ function getTimestamp () { - // next 3 lines taken from roslibjs action server example + // next few lines taken and adjusted from roslibjs action server example let currentTime = new Date() - let secs = Math.floor(currentTime.getTime()/1000) - let nsecs = Math.round(1000000000*(currentTime.getTime()/1000-secs)) + let secs = currentTime.getTime()/1000 // seconds before truncating the decimal + let secsFloored = Math.floor(secs) // seconds after truncating + let nsecs = Math.round(1000000000*(secs-secsFloored)) // nanoseconds since the previous second - return {secs : secs, nsecs : nsecs} + // return a dictionary for the ROS log and a float for the gui console + return [{secs : secsFloored, nsecs : nsecs}, secs] } function logGeneric (logLevel, message) { - timestamp = getTimestamp() - timeVal = timestamp.secs + timestamp.nsecs/10e8 - timeVal = timeVal.toFixed(3) + stamps = getTimestamp() + rosTimestamp = stamps[0] // dictionary for the ROS log message + consoleTimestamp = stamps[1].toFixed(3) // value for the console message switch (logLevel) { case ROSDEBUG: break case ROSINFO: //floor(timestamp.nsecs/1000, 2) - consoleMsg = "[INFO] " + '[' + timeVal + ']' + ': ' + message + consoleMsg = "[INFO] " + '[' + consoleTimestamp + ']' + ': ' + message console.log(consoleMsg) appendToConsole(consoleMsg, false) break case ROSWARN: - consoleMsg = "[WARN] " + '[' + timeVal + ']' + ': ' + message + consoleMsg = "[WARN] " + '[' + consoleTimestamp + ']' + ': ' + message console.error(consoleMsg) appendToConsole(consoleMsg, false) break case ROSERROR: - consoleMsg = "[ERROR] " + '[' + timeVal + ']' + ': ' + message + consoleMsg = "[ERROR] " + '[' + consoleTimestamp + ']' + ': ' + message console.error(consoleMsg) appendToConsole(consoleMsg, false) break case ROSFATAL: - consoleMsg = "[FATAL] " + '[' + timeVal + ']' + ': ' + message + consoleMsg = "[FATAL] " + '[' + consoleTimestamp + ']' + ': ' + message console.error(consoleMsg) appendToConsole(consoleMsg, false) break @@ -247,18 +249,19 @@ function logGeneric (logLevel, message) { ros_logger.publish( new ROSLIB.Message({ + // I'm only publishing the essentials. We could include more info if so desired header : { - // uint32 seq // sequence ID: consecutively increasing ID // seems to be automatic? - stamp : timestamp - // string frame_id // Frame this data is associated with // not relevant? + // seq // uint32: sequence ID, seems to increment automatically + stamp : rosTimestamp + // frame_id // string: probably only useful for tf }, level : logLevel, - // string name # name of the node + name : '/web_gui', // name of the node msg : message - // string file # file the message came from - // string function # function the message came from - // uint32 line # line the message came from - // string[] topics # topic names that the node publishes + // file : // string: we could specify the js file that generated the log + // function // string: we could specify the parent function that generated the log + // line // uint32: we could specify the specific line of code that generated the log + // topics // string[]: topic names that the node publishes }) ) } From d2e920d362a9894b8fcd5e22a75405299c7f7910 Mon Sep 17 00:00:00 2001 From: Josh Glazer Date: Tue, 11 Feb 2020 00:21:52 -0500 Subject: [PATCH 05/11] [#211] Replace time in seconds with hh:mm:ss format for gui console --- .../static/js/roslibjs/ros-helpers.js | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/robot/basestation/static/js/roslibjs/ros-helpers.js b/robot/basestation/static/js/roslibjs/ros-helpers.js index 9c83628d9..aa0052490 100644 --- a/robot/basestation/static/js/roslibjs/ros-helpers.js +++ b/robot/basestation/static/js/roslibjs/ros-helpers.js @@ -213,19 +213,22 @@ function getTimestamp () { let nsecs = Math.round(1000000000*(secs-secsFloored)) // nanoseconds since the previous second // return a dictionary for the ROS log and a float for the gui console - return [{secs : secsFloored, nsecs : nsecs}, secs] + return [{secs : secsFloored, nsecs : nsecs}, currentTime] } function logGeneric (logLevel, message) { stamps = getTimestamp() rosTimestamp = stamps[0] // dictionary for the ROS log message - consoleTimestamp = stamps[1].toFixed(3) // value for the console message + consoleTimestamp = stamps[1].toString().split(' ')[4] // hh:mm:ss from date object + // @TODO cedric can help me refactor this switch (logLevel) { case ROSDEBUG: + consoleMsg = "[DEBUG] " + '[' + consoleTimestamp + ']' + ': ' + message + console.log(consoleMsg) + appendToConsole(consoleMsg, false) break case ROSINFO: - //floor(timestamp.nsecs/1000, 2) consoleMsg = "[INFO] " + '[' + consoleTimestamp + ']' + ': ' + message console.log(consoleMsg) appendToConsole(consoleMsg, false) @@ -247,6 +250,9 @@ function logGeneric (logLevel, message) { break } + // @TODO bonus if we can determine how to generate a log file for the gui + // rather than simply having it show up in rosout.log + // an attempt was made with the name and file elements in the log message ros_logger.publish( new ROSLIB.Message({ // I'm only publishing the essentials. We could include more info if so desired @@ -256,9 +262,9 @@ function logGeneric (logLevel, message) { // frame_id // string: probably only useful for tf }, level : logLevel, - name : '/web_gui', // name of the node - msg : message - // file : // string: we could specify the js file that generated the log + // name : '/web_gui', // name of the node + msg : message, + // file : 'web_gui' // string: we could specify the js file that generated the log // function // string: we could specify the parent function that generated the log // line // uint32: we could specify the specific line of code that generated the log // topics // string[]: topic names that the node publishes From 81adb326fbeae47573d6eebcd39bbefc7bbbd8d5 Mon Sep 17 00:00:00 2001 From: Josh Glazer Date: Tue, 11 Feb 2020 18:58:01 -0500 Subject: [PATCH 06/11] [#211] Adjust comments, remove todos, rename logGeneric --- .../static/js/roslibjs/ros-helpers.js | 42 ++++++++----------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/robot/basestation/static/js/roslibjs/ros-helpers.js b/robot/basestation/static/js/roslibjs/ros-helpers.js index aa0052490..9f666998f 100644 --- a/robot/basestation/static/js/roslibjs/ros-helpers.js +++ b/robot/basestation/static/js/roslibjs/ros-helpers.js @@ -216,12 +216,14 @@ function getTimestamp () { return [{secs : secsFloored, nsecs : nsecs}, currentTime] } -function logGeneric (logLevel, message) { +function rosLog (logLevel, message) { stamps = getTimestamp() rosTimestamp = stamps[0] // dictionary for the ROS log message consoleTimestamp = stamps[1].toString().split(' ')[4] // hh:mm:ss from date object - // @TODO cedric can help me refactor this + // All log messages should go to the log file: currently goes to rosout.log + // unlike rospy, currently debug messages we generate will get published + // info goes to stdout, warn-error-fatal go to stderr switch (logLevel) { case ROSDEBUG: consoleMsg = "[DEBUG] " + '[' + consoleTimestamp + ']' + ': ' + message @@ -250,21 +252,18 @@ function logGeneric (logLevel, message) { break } - // @TODO bonus if we can determine how to generate a log file for the gui - // rather than simply having it show up in rosout.log - // an attempt was made with the name and file elements in the log message - ros_logger.publish( +ros_logger.publish( new ROSLIB.Message({ // I'm only publishing the essentials. We could include more info if so desired header : { // seq // uint32: sequence ID, seems to increment automatically - stamp : rosTimestamp + stamp : rosTimestamp // dictionary: contains truncated seconds and nanoseconds // frame_id // string: probably only useful for tf }, - level : logLevel, - // name : '/web_gui', // name of the node - msg : message, - // file : 'web_gui' // string: we could specify the js file that generated the log + level : logLevel, // int: see log level constants above + // name : '/web_gui', // name of the node (proposed) + msg : message, // string: this is the log message + // file // string: we could specify the js file that generated the log // function // string: we could specify the parent function that generated the log // line // uint32: we could specify the specific line of code that generated the log // topics // string[]: topic names that the node publishes @@ -272,29 +271,22 @@ function logGeneric (logLevel, message) { ) } -// Copying how rospy handles the logging functions: -// All log messages should go to the log file (but how?) -// debug messages only go to /rosout if a value is set while initializing the js -// info goes to stdout, warn-error-fatal go to stderr -// rospy also takes in *args and **kwargs, how does this work and do I need to implement that? +// these functions copy the rospy logging functions +// see the rosLog definition to see how each function's behaviour adjusted function logDebug (message) { - // @TODO only log debug messages if we set a parameter somewhere. - // in rospy this parameter is set when you initialize your node - // with: rospy.init_node(nodeName, log_level=rospy.DEBUG) - // for the webpage maybe we can set it when we run initRosWeb() - logGeneric(ROSDEBUG, message) + rosLog(ROSDEBUG, message) } function logInfo (message) { - logGeneric(ROSINFO, message) + rosLog(ROSINFO, message) } function logWarn (message) { - logGeneric(ROSWARN, message) + rosLog(ROSWARN, message) } function logErr (message) { - logGeneric(ROSERROR, message) + rosLog(ROSERROR, message) } function logFatal (message) { - logGeneric(ROSFATAL, message) + rosLog(ROSFATAL, message) } function requestMuxChannel (elemID, callback, timeout = REQUEST_TIMEOUT) { From 9c467427de48262e10eb8682706a47fa88275a51 Mon Sep 17 00:00:00 2001 From: Josh Glazer Date: Tue, 11 Feb 2020 23:58:04 -0500 Subject: [PATCH 07/11] [#211] Minor refactor timestamp function --- robot/basestation/static/js/roslibjs/ros-helpers.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/robot/basestation/static/js/roslibjs/ros-helpers.js b/robot/basestation/static/js/roslibjs/ros-helpers.js index 9f666998f..ea2b31628 100644 --- a/robot/basestation/static/js/roslibjs/ros-helpers.js +++ b/robot/basestation/static/js/roslibjs/ros-helpers.js @@ -212,14 +212,15 @@ function getTimestamp () { let secsFloored = Math.floor(secs) // seconds after truncating let nsecs = Math.round(1000000000*(secs-secsFloored)) // nanoseconds since the previous second - // return a dictionary for the ROS log and a float for the gui console - return [{secs : secsFloored, nsecs : nsecs}, currentTime] + // return a dictionary for the ROS log and a string for the gui console + let stampTime = currentTime.toString().split(' ')[4] + return [{secs : secsFloored, nsecs : nsecs}, stampTime] } function rosLog (logLevel, message) { stamps = getTimestamp() rosTimestamp = stamps[0] // dictionary for the ROS log message - consoleTimestamp = stamps[1].toString().split(' ')[4] // hh:mm:ss from date object + consoleTimestamp = stamps[1] // hh:mm:ss from date object // All log messages should go to the log file: currently goes to rosout.log // unlike rospy, currently debug messages we generate will get published From 3a985b836d3ee8e4aa07bb05a6a00967870ecd92 Mon Sep 17 00:00:00 2001 From: Josh Glazer Date: Wed, 12 Feb 2020 00:28:19 -0500 Subject: [PATCH 08/11] [#211] Refactor code to make it cleaner --- .../static/js/roslibjs/ros-helpers.js | 86 ++++++++++--------- 1 file changed, 46 insertions(+), 40 deletions(-) diff --git a/robot/basestation/static/js/roslibjs/ros-helpers.js b/robot/basestation/static/js/roslibjs/ros-helpers.js index ea2b31628..65c543815 100644 --- a/robot/basestation/static/js/roslibjs/ros-helpers.js +++ b/robot/basestation/static/js/roslibjs/ros-helpers.js @@ -213,52 +213,17 @@ function getTimestamp () { let nsecs = Math.round(1000000000*(secs-secsFloored)) // nanoseconds since the previous second // return a dictionary for the ROS log and a string for the gui console - let stampTime = currentTime.toString().split(' ')[4] + let stampTime = currentTime.toString().split(' ')[4] // hh:mm:ss from date object return [{secs : secsFloored, nsecs : nsecs}, stampTime] } -function rosLog (logLevel, message) { - stamps = getTimestamp() - rosTimestamp = stamps[0] // dictionary for the ROS log message - consoleTimestamp = stamps[1] // hh:mm:ss from date object - - // All log messages should go to the log file: currently goes to rosout.log - // unlike rospy, currently debug messages we generate will get published - // info goes to stdout, warn-error-fatal go to stderr - switch (logLevel) { - case ROSDEBUG: - consoleMsg = "[DEBUG] " + '[' + consoleTimestamp + ']' + ': ' + message - console.log(consoleMsg) - appendToConsole(consoleMsg, false) - break - case ROSINFO: - consoleMsg = "[INFO] " + '[' + consoleTimestamp + ']' + ': ' + message - console.log(consoleMsg) - appendToConsole(consoleMsg, false) - break - case ROSWARN: - consoleMsg = "[WARN] " + '[' + consoleTimestamp + ']' + ': ' + message - console.error(consoleMsg) - appendToConsole(consoleMsg, false) - break - case ROSERROR: - consoleMsg = "[ERROR] " + '[' + consoleTimestamp + ']' + ': ' + message - console.error(consoleMsg) - appendToConsole(consoleMsg, false) - break - case ROSFATAL: - consoleMsg = "[FATAL] " + '[' + consoleTimestamp + ']' + ': ' + message - console.error(consoleMsg) - appendToConsole(consoleMsg, false) - break - } - -ros_logger.publish( +function publishRosLog (logLevel, timestamp, message) { + ros_logger.publish( new ROSLIB.Message({ // I'm only publishing the essentials. We could include more info if so desired header : { // seq // uint32: sequence ID, seems to increment automatically - stamp : rosTimestamp // dictionary: contains truncated seconds and nanoseconds + stamp : timestamp // dictionary: contains truncated seconds and nanoseconds // frame_id // string: probably only useful for tf }, level : logLevel, // int: see log level constants above @@ -272,9 +237,50 @@ ros_logger.publish( ) } +function rosLog (logLevel, message) { + let prefix, isError + switch (logLevel) { + case ROSDEBUG: + // unlike rospy, currently the debug messages we generate will get published + prefix = '[DEBUG]' + isError = false + break + case ROSINFO: + prefix = '[INFO]' + isError = false + break + case ROSWARN: + prefix = '[WARN]' + isError = true + break + case ROSERROR: + prefix = '[ERROR]' + isError = true + break + case ROSFATAL: + prefix = '[FATAL]' + isError = true + break + } + + stamps = getTimestamp() + consoleMsg = prefix + ' [' + stamps[1] + ']: ' + message + + // info goes to stdout, warn-error-fatal go to stderr + if (!isError) { + console.log(consoleMsg) + } else { + console.error(consoleMsg) + } + appendToConsole(consoleMsg, false) + + // All log messages should go to the log file: currently goes to rosout.log + publishRosLog(logLevel, stamps[0], message) +} + // these functions copy the rospy logging functions -// see the rosLog definition to see how each function's behaviour adjusted function logDebug (message) { + // unlike rospy, currently the debug messages we generate will get published rosLog(ROSDEBUG, message) } function logInfo (message) { From 7517562ca7b900ceed3a7e9b499189e7bee82725 Mon Sep 17 00:00:00 2001 From: Josh Glazer Date: Thu, 13 Feb 2020 17:05:39 -0500 Subject: [PATCH 09/11] [#211] Fix recommended changes by smartens Co-authored-by: MartensCedric --- .../static/js/roslibjs/ros-helpers.js | 54 ++++++------------- 1 file changed, 16 insertions(+), 38 deletions(-) diff --git a/robot/basestation/static/js/roslibjs/ros-helpers.js b/robot/basestation/static/js/roslibjs/ros-helpers.js index 65c543815..df8619a0b 100644 --- a/robot/basestation/static/js/roslibjs/ros-helpers.js +++ b/robot/basestation/static/js/roslibjs/ros-helpers.js @@ -205,7 +205,7 @@ function initRosWeb () { /* functions used in main code */ -function getTimestamp () { +function rosTimestamp () { // next few lines taken and adjusted from roslibjs action server example let currentTime = new Date() let secs = currentTime.getTime()/1000 // seconds before truncating the decimal @@ -238,49 +238,27 @@ function publishRosLog (logLevel, timestamp, message) { } function rosLog (logLevel, message) { - let prefix, isError - switch (logLevel) { - case ROSDEBUG: - // unlike rospy, currently the debug messages we generate will get published - prefix = '[DEBUG]' - isError = false - break - case ROSINFO: - prefix = '[INFO]' - isError = false - break - case ROSWARN: - prefix = '[WARN]' - isError = true - break - case ROSERROR: - prefix = '[ERROR]' - isError = true - break - case ROSFATAL: - prefix = '[FATAL]' - isError = true - break - } - - stamps = getTimestamp() - consoleMsg = prefix + ' [' + stamps[1] + ']: ' + message - - // info goes to stdout, warn-error-fatal go to stderr - if (!isError) { - console.log(consoleMsg) - } else { - console.error(consoleMsg) - } + logData = {} + logData[ROSDEBUG] = {prefix : '[DEBUG]', isError : false} + logData[ROSINFO] = {prefix : '[INFO]', isError : false} + logData[ROSWARN] = {prefix : '[WARN]', isError : true} + logData[ROSERROR] = {prefix : '[ERROR]', isError : true} + logData[ROSFATAL] = {prefix : '[FATAL]', isError : true} + console.log(message) + stamps = rosTimestamp() + consoleMsg = logData[logLevel].prefix + ' [' + stamps[1] + ']: ' + message + + !logData[logLevel].isError + ? console.log(consoleMsg) + : console.error(consoleMsg) appendToConsole(consoleMsg, false) - - // All log messages should go to the log file: currently goes to rosout.log + // log messages go to log file: currently rosout.log publishRosLog(logLevel, stamps[0], message) } // these functions copy the rospy logging functions function logDebug (message) { - // unlike rospy, currently the debug messages we generate will get published + // unlike rospy, (currently) the debug messages we generate will get published rosLog(ROSDEBUG, message) } function logInfo (message) { From 0ab21c3386e6c70f22e588c56543ddbf460fc542 Mon Sep 17 00:00:00 2001 From: MartensCedric Date: Thu, 13 Feb 2020 17:25:29 -0500 Subject: [PATCH 10/11] [#211] Remove useless console.log --- robot/basestation/static/js/roslibjs/ros-helpers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/robot/basestation/static/js/roslibjs/ros-helpers.js b/robot/basestation/static/js/roslibjs/ros-helpers.js index df8619a0b..9f9d30e14 100644 --- a/robot/basestation/static/js/roslibjs/ros-helpers.js +++ b/robot/basestation/static/js/roslibjs/ros-helpers.js @@ -244,7 +244,7 @@ function rosLog (logLevel, message) { logData[ROSWARN] = {prefix : '[WARN]', isError : true} logData[ROSERROR] = {prefix : '[ERROR]', isError : true} logData[ROSFATAL] = {prefix : '[FATAL]', isError : true} - console.log(message) + stamps = rosTimestamp() consoleMsg = logData[logLevel].prefix + ' [' + stamps[1] + ']: ' + message From 57ade019282a02c07e151c2434e61391c62ec608 Mon Sep 17 00:00:00 2001 From: Josh Glazer Date: Fri, 14 Feb 2020 22:12:35 -0500 Subject: [PATCH 11/11] [#211] Adjust code based on Peter's request --- .../static/js/roslibjs/ros-helpers.js | 66 ++++++++++++++++--- 1 file changed, 56 insertions(+), 10 deletions(-) diff --git a/robot/basestation/static/js/roslibjs/ros-helpers.js b/robot/basestation/static/js/roslibjs/ros-helpers.js index 9f9d30e14..42d5cab66 100644 --- a/robot/basestation/static/js/roslibjs/ros-helpers.js +++ b/robot/basestation/static/js/roslibjs/ros-helpers.js @@ -9,6 +9,7 @@ const ROSWARN = 4 // warning level const ROSERROR = 8 // error level const ROSFATAL = 16 // fatal/critical level +// function initRosWeb () { ros = new ROSLIB.Ros({ url: 'ws://' + env.HOST_IP + ':9090' @@ -205,18 +206,28 @@ function initRosWeb () { /* functions used in main code */ +/** + * Gets the current time and formats it for ROS and the GUI. + * @return array of two variables: ROS time object, string containing hh:mm:ss +*/ function rosTimestamp () { // next few lines taken and adjusted from roslibjs action server example let currentTime = new Date() let secs = currentTime.getTime()/1000 // seconds before truncating the decimal let secsFloored = Math.floor(secs) // seconds after truncating - let nsecs = Math.round(1000000000*(secs-secsFloored)) // nanoseconds since the previous second + let nanoSecs = Math.round(1000000000*(secs-secsFloored)) // nanoseconds since the previous second // return a dictionary for the ROS log and a string for the gui console let stampTime = currentTime.toString().split(' ')[4] // hh:mm:ss from date object - return [{secs : secsFloored, nsecs : nsecs}, stampTime] + return [{secs : secsFloored, nsecs : nanoSecs}, stampTime] } +/** + * Creates and publishes a ROS log message to /rosout based on the parameters + * @param logLevel one of the ROS loglevel constants defined above + * @param timestamp ros time object containing seconds and nanoseconds + * @param message the log message +*/ function publishRosLog (logLevel, timestamp, message) { ros_logger.publish( new ROSLIB.Message({ @@ -237,39 +248,74 @@ function publishRosLog (logLevel, timestamp, message) { ) } +/** + * Prints the log message to the GUI and chrome console. + * Also calls publishRosLog with the message and parameters. + * @param logLevel one of the ROS loglevel constants defined above + * @param message the log message +*/ function rosLog (logLevel, message) { logData = {} - logData[ROSDEBUG] = {prefix : '[DEBUG]', isError : false} - logData[ROSINFO] = {prefix : '[INFO]', isError : false} - logData[ROSWARN] = {prefix : '[WARN]', isError : true} - logData[ROSERROR] = {prefix : '[ERROR]', isError : true} - logData[ROSFATAL] = {prefix : '[FATAL]', isError : true} + logData[ROSDEBUG] = {prefix : '[DEBUG]', type : 'log'} + logData[ROSINFO] = {prefix : '[INFO]', type : 'log'} + logData[ROSWARN] = {prefix : '[WARN]', type : 'warn'} + logData[ROSERROR] = {prefix : '[ERROR]', type : 'error'} + logData[ROSFATAL] = {prefix : '[FATAL]', type : 'error'} stamps = rosTimestamp() consoleMsg = logData[logLevel].prefix + ' [' + stamps[1] + ']: ' + message - !logData[logLevel].isError - ? console.log(consoleMsg) - : console.error(consoleMsg) + if (logData[logLevel].type === 'log') { + console.log(consoleMsg) + } else if (logData[logLevel].type === 'warn') { + console.warn(consoleMsg) + } else if (logData[logLevel].type === 'error') { + console.error(consoleMsg) + } appendToConsole(consoleMsg, false) // log messages go to log file: currently rosout.log publishRosLog(logLevel, stamps[0], message) } // these functions copy the rospy logging functions +/** + * Sends a debug message with timestamp to the GUI and chrome consoles. + * Also publishes it to /rosout. + * @param message the log message +*/ function logDebug (message) { // unlike rospy, (currently) the debug messages we generate will get published rosLog(ROSDEBUG, message) } +/** + * Sends an info message with timestamp to the GUI and chrome consoles. + * Also publishes it to /rosout. + * @param message the log message +*/ function logInfo (message) { rosLog(ROSINFO, message) } +/** + * Sends a warning message with timestamp to the GUI and chrome consoles. + * Also publishes it to /rosout. + * @param message the log message +*/ function logWarn (message) { rosLog(ROSWARN, message) } +/** + * Sends an error message with timestamp to the GUI and chrome consoles. + * Also publishes it to /rosout. + * @param message the log message +*/ function logErr (message) { rosLog(ROSERROR, message) } +/** + * Sends a fatal error message with timestamp to the GUI and chrome consoles. + * Also publishes it to /rosout. + * @param message the log message +*/ function logFatal (message) { rosLog(ROSFATAL, message) }