Programming languages

How to set matplotlib X axis timestamp format to hours and minutes

import matplotlib.dates as mdates

plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))

 

Posted by Uli Köhler in Python

How to change matplotlib X axis timestamp format

Sometimes you get weird timestamp format choices in Matplotlib such as 22 19:40 (meaning 19:40 o’clock on the 22nd of whatever month).

This is easy to fix:

import matplotlib.dates as mdates

plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))

which will result in this image, for example:

Posted by Uli Köhler in Python

How to get first day of next month in Javascript using DayJS

See the dayjs docs for more info about the library.

const now = dayjs();
const nextMonth = now.month(now.month() + 1).date(1).hour(0).minute(0).second(0);

// Example usage
console.info(nextMonth.format())
// Prints, for example, "2022-03-01T00:00:00+01:00"

This will also work in december as DayJS processes month(13) correctly:

const now = dayjs('2021-12-09');
const nextMonth = now.month(now.month() + 1).date(1).hour(0).minute(0).second(0);

// This prints '2022-01-01T00:00:00+01:00'
console.info(nextMonth.format());

 

Posted by Uli Köhler in Javascript

How to reverse std::string using std::reverse (C++)

#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

int main(int argc, char** argv) {
    std::string s = "My string";
    // This reverses s in-place.
    std::reverse(std::begin(s), std::end(s));
    // Prints "gnirts yM"
    cout << s << endl;
}

 

Posted by Uli Köhler in C/C++

re2 C++ replace (GlobalReplace) minimal example

This minimal example shows how to replace strings using the re2 GlobalReplace() function:

#include <re2/re2.h>
#include <iostream>
#include <string>

using namespace re2;
using namespace std;

// Pre-compiled regex
RE2 myRegex("\\$[^\\$]+\\$");

int main(int argc, char** argv) {
    string myString = "This string $abc123$ contains two formulas $123 != 456$.";
    // NOTE: This will modify myString!
    RE2::GlobalReplace(&myString, myRegex, "FORMULA");
    // Prints "This string FORMULA contains two formulas FORMULA."
    cout << myString << endl;
}

 

Posted by Uli Köhler in C/C++

re2 C++ regular expressions library: How to #include?

#include <re2/re2.h>

using namespace re2;

 

Posted by Uli Köhler in C/C++

cpp-httplib: How to get query parameters

This example shows how to get a query parameter in cpp-httplib. See the cpp-httplib hello example for the full source code:

svr.Get("/hi", [](const httplib::Request& req, httplib::Response& res) {
    std::string id = req.get_param_value("id");
    res.set_content("id=" + id, "text/plain");
});

Access it at http://localhost:8080/hi?id=myid

and it will show you

id=myid

id will be empty (== "") if no such parameter is given.

Posted by Uli Köhler in C/C++

How to fix Paho MQTT undefined reference to `SHA1_Init’

Problem:

When trying to build your C++ application using Paho MQTT, you see a bunch of undefined reference error messages:

MQTTAsync.c:(.text+0x3482): undefined reference to `OpenSSL_version'
/usr/bin/ld: MQTTAsync.c:(.text+0x34a1): undefined reference to `OpenSSL_version'
/usr/bin/ld: MQTTAsync.c:(.text+0x34c0): undefined reference to `OpenSSL_version'
/usr/bin/ld: MQTTAsync.c:(.text+0x34df): undefined reference to `OpenSSL_version'
/usr/bin/ld: MQTTAsync.c:(.text+0x34fe): undefined reference to `OpenSSL_version'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(MQTTAsyncUtils.c.o): in function `MQTTAsync_closeOnly':
MQTTAsyncUtils.c:(.text+0x9b6): undefined reference to `SSL_SESSION_free'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(MQTTAsyncUtils.c.o): in function `MQTTAsync_receiveThread':
MQTTAsyncUtils.c:(.text+0x463b): undefined reference to `SSL_set_session'
/usr/bin/ld: MQTTAsyncUtils.c:(.text+0x5255): undefined reference to `SSL_get1_session'
/usr/bin/ld: MQTTAsyncUtils.c:(.text+0x55bb): undefined reference to `SSL_get1_session'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(SSLSocket.c.o): in function `call_ssl_psk_cb':
SSLSocket.c:(.text+0x11b): undefined reference to `SSL_get_SSL_CTX'
/usr/bin/ld: SSLSocket.c:(.text+0x129): undefined reference to `SSL_CTX_get_ex_data'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(SSLSocket.c.o): in function `SSLSocket_error':
SSLSocket.c:(.text+0x1fa): undefined reference to `SSL_get_error'
/usr/bin/ld: SSLSocket.c:(.text+0x22d): undefined reference to `ERR_print_errors_cb'
/usr/bin/ld: SSLSocket.c:(.text+0x2f1): undefined reference to `ERR_get_error'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(SSLSocket.c.o): in function `SSL_CTX_info_callback':
SSLSocket.c:(.text+0x376): undefined reference to `SSL_alert_desc_string_long'
/usr/bin/ld: SSLSocket.c:(.text+0x381): undefined reference to `SSL_alert_type_string_long'
/usr/bin/ld: SSLSocket.c:(.text+0x3bc): undefined reference to `SSL_get_verify_result'
/usr/bin/ld: SSLSocket.c:(.text+0x411): undefined reference to `SSL_state_string_long'
/usr/bin/ld: SSLSocket.c:(.text+0x461): undefined reference to `SSL_get_current_cipher'
/usr/bin/ld: SSLSocket.c:(.text+0x469): undefined reference to `SSL_CIPHER_get_name'
/usr/bin/ld: SSLSocket.c:(.text+0x474): undefined reference to `SSL_state_string_long'
/usr/bin/ld: SSLSocket.c:(.text+0x4d1): undefined reference to `SSL_alert_desc_string_long'
/usr/bin/ld: SSLSocket.c:(.text+0x4dc): undefined reference to `SSL_alert_type_string_long'
/usr/bin/ld: SSLSocket.c:(.text+0x4e7): undefined reference to `SSL_state_string_long'
/usr/bin/ld: SSLSocket.c:(.text+0x503): undefined reference to `SSL_alert_desc_string_long'
/usr/bin/ld: SSLSocket.c:(.text+0x50e): undefined reference to `SSL_alert_type_string_long'
/usr/bin/ld: SSLSocket.c:(.text+0x541): undefined reference to `SSL_alert_desc_string_long'
/usr/bin/ld: SSLSocket.c:(.text+0x54c): undefined reference to `SSL_alert_type_string_long'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(SSLSocket.c.o): in function `SSLSocket_initialize':
SSLSocket.c:(.text+0x8ee): undefined reference to `OPENSSL_init_ssl'
/usr/bin/ld: SSLSocket.c:(.text+0x90a): undefined reference to `OPENSSL_init_crypto'
/usr/bin/ld: SSLSocket.c:(.text+0x916): undefined reference to `OPENSSL_init_ssl'
/usr/bin/ld: SSLSocket.c:(.text+0x922): undefined reference to `OPENSSL_init_crypto'
/usr/bin/ld: SSLSocket.c:(.text+0xa11): undefined reference to `CRYPTO_get_ex_new_index'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(SSLSocket.c.o): in function `SSLSocket_createContext':
SSLSocket.c:(.text+0xbee): undefined reference to `SSL_CTX_use_certificate_chain_file'
/usr/bin/ld: SSLSocket.c:(.text+0xc48): undefined reference to `SSL_CTX_set_default_passwd_cb'
/usr/bin/ld: SSLSocket.c:(.text+0xc55): undefined reference to `SSL_CTX_set_default_passwd_cb_userdata'
/usr/bin/ld: SSLSocket.c:(.text+0xc67): undefined reference to `SSL_CTX_use_PrivateKey_file'
/usr/bin/ld: SSLSocket.c:(.text+0xc9a): undefined reference to `SSL_CTX_load_verify_locations'
/usr/bin/ld: SSLSocket.c:(.text+0xce5): undefined reference to `SSL_CTX_set_default_verify_paths'
/usr/bin/ld: SSLSocket.c:(.text+0xd2e): undefined reference to `SSL_CTX_set_cipher_list'
/usr/bin/ld: SSLSocket.c:(.text+0xd56): undefined reference to `SSL_CTX_set_ex_data'
/usr/bin/ld: SSLSocket.c:(.text+0xd66): undefined reference to `SSL_CTX_set_psk_client_callback'
/usr/bin/ld: SSLSocket.c:(.text+0xd8f): undefined reference to `SSL_CTX_ctrl'
/usr/bin/ld: SSLSocket.c:(.text+0xdc5): undefined reference to `SSL_CTX_free'
/usr/bin/ld: SSLSocket.c:(.text+0xe51): undefined reference to `SSL_CTX_set_alpn_protos'
/usr/bin/ld: SSLSocket.c:(.text+0xeb9): undefined reference to `TLS_client_method'
/usr/bin/ld: SSLSocket.c:(.text+0xec1): undefined reference to `SSL_CTX_new'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(SSLSocket.c.o): in function `SSLSocket_setSocketForSSL':
SSLSocket.c:(.text+0x1046): undefined reference to `SSL_CTX_set_info_callback'
/usr/bin/ld: SSLSocket.c:(.text+0x1056): undefined reference to `SSL_CTX_set_msg_callback'
/usr/bin/ld: SSLSocket.c:(.text+0x1075): undefined reference to `SSL_new'
/usr/bin/ld: SSLSocket.c:(.text+0x10ab): undefined reference to `SSL_get_cipher_list'
/usr/bin/ld: SSLSocket.c:(.text+0x10be): undefined reference to `SSL_set_fd'
/usr/bin/ld: SSLSocket.c:(.text+0x113b): undefined reference to `SSL_ctrl'
/usr/bin/ld: SSLSocket.c:(.text+0x121c): undefined reference to `SSL_CTX_set_verify'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(SSLSocket.c.o): in function `SSLSocket_connect':
SSLSocket.c:(.text+0x12b7): undefined reference to `ERR_clear_error'
/usr/bin/ld: SSLSocket.c:(.text+0x12bf): undefined reference to `SSL_connect'
/usr/bin/ld: SSLSocket.c:(.text+0x135d): undefined reference to `SSL_get_peer_certificate'
/usr/bin/ld: SSLSocket.c:(.text+0x138c): undefined reference to `X509_check_host'
/usr/bin/ld: SSLSocket.c:(.text+0x13d4): undefined reference to `CRYPTO_free'
/usr/bin/ld: SSLSocket.c:(.text+0x13f6): undefined reference to `X509_free'
/usr/bin/ld: SSLSocket.c:(.text+0x144d): undefined reference to `X509_check_ip_asc'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(SSLSocket.c.o): in function `SSLSocket_getch':
SSLSocket.c:(.text+0x1569): undefined reference to `ERR_clear_error'
/usr/bin/ld: SSLSocket.c:(.text+0x1579): undefined reference to `SSL_read'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(SSLSocket.c.o): in function `SSLSocket_destroyContext':
SSLSocket.c:(.text+0x1630): undefined reference to `SSL_CTX_free'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(SSLSocket.c.o): in function `SSLSocket_close':
SSLSocket.c:(.text+0x16b8): undefined reference to `ERR_clear_error'
/usr/bin/ld: SSLSocket.c:(.text+0x16c1): undefined reference to `SSL_shutdown'
/usr/bin/ld: SSLSocket.c:(.text+0x16ce): undefined reference to `SSL_free'
/usr/bin/ld: SSLSocket.c:(.text+0x16fd): undefined reference to `SSL_CTX_free'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(SSLSocket.c.o): in function `SSLSocket_putdatas':
SSLSocket.c:(.text+0x191f): undefined reference to `ERR_clear_error'
/usr/bin/ld: SSLSocket.c:(.text+0x1930): undefined reference to `SSL_write'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(SSLSocket.c.o): in function `SSLSocket_getdata':
SSLSocket.c:(.text+0x1ca5): undefined reference to `ERR_clear_error'
/usr/bin/ld: SSLSocket.c:(.text+0x1cb8): undefined reference to `SSL_read'
/usr/bin/ld: SSLSocket.c:(.text+0x1d7f): undefined reference to `SSL_pending'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(SSLSocket.c.o): in function `SSLSocket_continueWrite':
SSLSocket.c:(.text+0x1e2f): undefined reference to `ERR_clear_error'
/usr/bin/ld: SSLSocket.c:(.text+0x1e3f): undefined reference to `SSL_write'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(Base64.c.o): in function `Base64_encodeDecode.part.0':
Base64.c:(.text+0x1f): undefined reference to `BIO_f_base64'
/usr/bin/ld: Base64.c:(.text+0x27): undefined reference to `BIO_new'
/usr/bin/ld: Base64.c:(.text+0x2f): undefined reference to `BIO_s_mem'
/usr/bin/ld: Base64.c:(.text+0x37): undefined reference to `BIO_new'
/usr/bin/ld: Base64.c:(.text+0x45): undefined reference to `BIO_push'
/usr/bin/ld: Base64.c:(.text+0x55): undefined reference to `BIO_set_flags'
/usr/bin/ld: Base64.c:(.text+0x78): undefined reference to `BIO_write'
/usr/bin/ld: Base64.c:(.text+0x8e): undefined reference to `BIO_ctrl'
/usr/bin/ld: Base64.c:(.text+0x9e): undefined reference to `BIO_free_all'
/usr/bin/ld: Base64.c:(.text+0xc1): undefined reference to `BIO_read'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(WebSocket.c.o): in function `WebSocket_buildFrame.constprop.0':
WebSocket.c:(.text+0x441): undefined reference to `RAND_bytes'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(WebSocket.c.o): in function `uuid_generate':
WebSocket.c:(.text+0x721): undefined reference to `RAND_bytes'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(WebSocket.c.o): in function `WebSocket_connect':
WebSocket.c:(.text+0x929): undefined reference to `RAND_bytes'
/usr/bin/ld: /home/uli/.conan/data/paho-mqtt-c/1.3.9/_/_/package/6fbd1993993594bd3f9451023a96c5ec2eef0e19/lib/libpaho-mqtt3as.a(WebSocket.c.o): in function `WebSocket_upgrade':
WebSocket.c:(.text+0x1dd9): undefined reference to `SHA1_Init'
/usr/bin/ld: WebSocket.c:(.text+0x1def): undefined reference to `SHA1_Update'
/usr/bin/ld: WebSocket.c:(.text+0x1dff): undefined reference to `SHA1_Final'
collect2: error: ld returned 1 exit status

Solution

In addition to linking the Paho MQTT libraries, you also need to link OpenSSL, i.e. the ssl and crypto libraries. You can link them, for example using

target_link_libraries(myexecutable ssl crypto)

in CMake or by adding these linker flags for GCC:

-lssl -lcrypto

 

Posted by Uli Köhler in C/C++

How to link Paho MQTT C++ binding using CMake

target_link_libraries(myexecutable paho-mqttpp3 paho-mqtt3as ssl crypto)

 

Posted by Uli Köhler in C/C++, MQTT

How to initialize new C++ executable project using conan 1.x

Important note: This post is for Conan 1.x and is not compatible with the current version conan 2.x! See How to initialize C++ project using conan 2.x for an updated version of this post!

In the directory where you want to create the project, run (obviously, replace mypackageby the name of everywhere in our code!)

conan new mypackage/1.0.0 -s

-s is important here. It tells conan that the source is available in the project directory and it should not be pulled using git etc.

This will initialize a shared library project, which we will now modify to build an executable.

First, open src/CMakeLists.txt and change add_library() to add_executable(), for example

add_library(mypackage mypackage.cpp)

to

add_executable(mypackage mypackage.cpp)

Now we shall modify conanfile.py to properly build & install the executable:

    def package(self):
        self.copy("*.h", dst="include", src="src")
        self.copy("*.lib", dst="lib", keep_path=False)
        self.copy("*.dll", dst="bin", keep_path=False)
        self.copy("*.dylib*", dst="lib", keep_path=False)
        self.copy("*.so", dst="lib", keep_path=False)
        self.copy("*.a", dst="lib", keep_path=False)
    def package_info(self):
        self.cpp_info.libs = ["NoxecoDB"]

with

    def package(self):
        self.copy("mypackage", src="bin", dst="bin", keep_path=False)

    def package_info(self):
        self.env_info.PATH = os.path.join(self.package_folder, "bin")

    def deploy(self):
        self.copy("mypackage", dst="bin", src="bin")

and add

import os.path

to the top of the file

Now let’s add a main() function to  src/mypackage.cpp. Replace the file’s content with

#include <iostream>

int main(int argc, char** argv) {
    std::cout << "Hello World!" <<std::endl;
}

Now it’s time to install the dependencies & build the project using

conan install . && conan build .

The executable will be in

bin/mypackage

You can run it using

./bin/mypackage

which will print

Hello World!

I also recommend to add this .gitignore:

CMakeCache.txt
CMakeFiles/
Makefile
bin/
cmake_install.cmake
conan.lock
conanbuildinfo.cmake
conanbuildinfo.txt
conaninfo.txt
graph_info.json

 

Posted by Uli Köhler in C/C++, Conan

LinuxCNC: How to get current position including offset using Python

In our previous example LinuxCNC: How to find current position using Python we showed how to use stat.actual_position to get the current position in machine coordinates using LinuxCNC’s Python API.

#!/usr/bin/env python2.7
import linuxcnc

stat = linuxcnc.stat()
stat.poll()
x,y,z,a,b,c,u,v,w = stat.actual_position

# NOTE: Ignore ABCUVW since not used for my machine
# Subtract G5x offset
xo,yo,zo,ao,bo,co,uo,vo,wo = stat.g5x_offset

x -= xo
y -= yo
z -= zo

# Subtract tool offset
xo,yo,zo,ao,bo,co,uo,vo,wo = stat.tool_offset

x -= xo
y -= yo
z -= zo

# Print offset coordinates
print(x,y,z)

 

Posted by Uli Köhler in LinuxCNC, Python

LinuxCNC: What attributes can you read from a linuxcnc.stat() object?

As shown in our previous example LinuxCNC: How to find current position using Python you can get an

These are the attributes of the object returned by linuxcnc.stat() for LinuxCNC 2.7:

acceleration
active_queue
actual_position
adaptive_feed_enabled
ain
angular_units
aout
axes
axis
axis_mask
block_delete
call_level
command
current_line
current_vel
cycle_time
debug
delay_left
din
distance_to_go
dout
dtg
echo_serial_number
enabled
estop
exec_state
feed_hold_enabled
feed_override_enabled
feedrate
file
flood
g5x_index
g5x_offset
g92_offset
gcodes
homed
id
inpos
input_timeout
interp_state
interpreter_errcode
joint_actual_position
joint_position
kinematics_type
limit
linear_units
lube
lube_level
max_acceleration
max_velocity
mcodes
mist
motion_line
motion_mode
motion_type
optional_stop
paused
pocket_prepped
poll
position
probe_tripped
probe_val
probed_position
probing
program_units
queue
queue_full
queued_mdi_commands
rapidrate
read_line
rotation_xy
settings
spindle_brake
spindle_direction
spindle_enabled
spindle_increasing
spindle_override_enabled
spindle_speed
spindlerate
state
task_mode
task_paused
task_state
tool_in_spindle
tool_offset
tool_table
velocity

You can find those out using

#!/usr/bin/env python2.7
import linuxcnc

stat = linuxcnc.stat()
stat.poll()
for entry in dir(stat):
    print(entry)

 

Posted by Uli Köhler in LinuxCNC, Python

LinuxCNC: How to find current position using Python

This will show the position in machine coordinates such as

#!/usr/bin/env python2.7
import linuxcnc

stat = linuxcnc.stat()
stat.poll()
print(stat.actual_position)

Example output:

(7.4023762662053105, 26.443582149595567, 297.289833343029, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)

 

Posted by Uli Köhler in LinuxCNC, Python

LinuxCNC: Custom M-100 G-Code that logs time, parameters & filename to CSV

Place this file in e.g. linuxcnc/configs/myCNC/custom-mcode/M100

#!/usr/bin/env python2.7
# M100: write timestamp, parameters and gcode filename to linuxcnc/logM100.txt
import sys
import linuxcnc
from datetime import datetime
dt = datetime.now()

stat = linuxcnc.stat() # create a connection to the status channel
stat.poll()

with open("/home/cnc/linuxcnc/logM100.txt", "a") as outfile:
    outfile.write("{} | Args={} | Path={}\n".format(dt.isoformat(), ", ".join(sys.argv[1:]), stat.file))

and make executable using

chmod a+x ./linuxcnc/configs/myCNC/custom-mcodes/M100
Posted by Uli Köhler in LinuxCNC, Python

LinuxCNC: How to read current position in Python and log to CSV

Also see our post on how to just read the position especially if you don’t care about the CSV logging: LinuxCNC: How to find current position using Python

This script will log the position to CSV approximately every millisecond. The position will be logged in machine coordinates.

#!/usr/bin/env python2.7
import linuxcnc
import datetime
import time

stat = linuxcnc.stat()

with open("position-log.csv", "w") as outfile:
    while True:
       dt = datetime.datetime.now()
       stat.poll()
       x,y,z,a,b,c,u,v,w = stat.actual_position
       outfile.write("{},{:.4f},{:.4f},{:.4f}\n".format(dt.isoformat(), x, y, z))
       time.sleep(0.001)

 

Posted by Uli Köhler in LinuxCNC, Python

How to parse linuxcnc.var using Python

with open("/home/cnc/linuxcnc/configs/myCNC/linuxcnc.var") as infile:
    lines = infile.readlines()
    splitted = [line.strip().partition("\t") for line in lines]
    linuxCNCVar = {int(splitResult[0]): float(splitResult[-1]) for splitResult in splitted}

Example output for linuxCNCVar:

{5161: 0.0,
 5162: 0.0,
 5163: 0.0,
 5164: 0.0,
 5165: 0.0,
 5166: 0.0,
 5167: 0.0,
 5168: 0.0,
 5169: 0.0,
 5181: 0.0,
 5182: 0.0,
 5183: 0.0,
 5184: 0.0,
 5185: 0.0,
 5186: 0.0,
 5187: 0.0,
 5188: 0.0,
 5189: 0.0,
 5210: 0.0,
 5211: 0.0,
 5212: 0.0,
 5213: 0.0,
 5214: 0.0,
 5215: 0.0,
 5216: 0.0,
 5217: 0.0,
 5218: 0.0,
 5219: 0.0,
 5220: 1.0,
 5221: 7.40119,
 5222: 13.549249,
 5223: 298.476583,
 5224: 0.0,
 5225: 0.0,
 5226: 0.0,
 5227: 0.0,
 5228: 0.0,
 5229: 0.0,
 5230: 0.0,
 5241: 36.868548,
 5242: 141.752329,
 5243: 207.563262,
 5244: 0.0,
 5245: 0.0,
 5246: 0.0,
 5247: 0.0,
 5248: 0.0,
 5249: 0.0,
 5250: 0.0,
 5261: 36.868548,
 5262: 145.029329,
 5263: 207.563262,
 5264: 0.0,
 5265: 0.0,
 5266: 0.0,
 5267: 0.0,
 5268: 0.0,
 5269: 0.0,
 5270: 0.0,
 5281: 36.89201,
 5282: 144.834924,
 5283: 207.935105,
 5284: 0.0,
 5285: 0.0,
 5286: 0.0,
 5287: 0.0,
 5288: 0.0,
 5289: 0.0,
 5290: 0.0,
 5301: 0.0,
 5302: 0.0,
 5303: 0.0,
 5304: 0.0,
 5305: 0.0,
 5306: 0.0,
 5307: 0.0,
 5308: 0.0,
 5309: 0.0,
 5310: 0.0,
 5321: 0.0,
 5322: 0.0,
 5323: 0.0,
 5324: 0.0,
 5325: 0.0,
 5326: 0.0,
 5327: 0.0,
 5328: 0.0,
 5329: 0.0,
 5330: 0.0,
 5341: 0.0,
 5342: 0.0,
 5343: 0.0,
 5344: 0.0,
 5345: 0.0,
 5346: 0.0,
 5347: 0.0,
 5348: 0.0,
 5349: 0.0,
 5350: 0.0,
 5361: 0.0,
 5362: 0.0,
 5363: 0.0,
 5364: 0.0,
 5365: 0.0,
 5366: 0.0,
 5367: 0.0,
 5368: 0.0,
 5369: 0.0,
 5370: 0.0,
 5381: 0.0,
 5382: 0.0,
 5383: 0.0,
 5384: 0.0,
 5385: 0.0,
 5386: 0.0,
 5387: 0.0,
 5388: 0.0,
 5389: 0.0,
 5390: 0.0}

 

Posted by Uli Köhler in LinuxCNC, Python

How to fix tox AttributeError: module ‘virtualenv.create.via_global_ref.builtin.cpython.mac_os’ has no attribute ‘CPython2macOsArmFramework’

Problem:

While trying to run Python tests using tox, you see an error message like

GLOB sdist-make: /home/uli/dev/UliEngineering/setup.py
py37 create: /home/uli/dev/UliEngineering/.tox/py37
ERROR: InterpreterNotFound: python3.7
py38 create: /home/uli/dev/UliEngineering/.tox/py38
ERROR: invocation failed (exit code 1), logfile: /home/uli/dev/UliEngineering/.tox/py38/log/py38-0.log
========================================================================================= log start =========================================================================================
AttributeError: module 'virtualenv.create.via_global_ref.builtin.cpython.mac_os' has no attribute 'CPython2macOsArmFramework'

========================================================================================== log end ==========================================================================================
ERROR: InvocationError for command /usr/bin/python3 -m virtualenv --no-download --python /usr/bin/python3 py38 (exited with code 1)
__________________________________________________________________________________________ summary __________________________________________________________________________________________
ERROR:  py37: InterpreterNotFound: python3.7
ERROR:   py38: InvocationError for command /usr/bin/python3 -m virtualenv --no-download --python /usr/bin/python3 py38 (exited with code 1)

Solution:

This error occurs because two different and incompatible version of virtualenv are installed.

First, uninstall all versions using these commands:

First run as user (not as root) to uninstall any locally installed package in ~/.local:

pip3 uninstall virtualenv

Then, uninstall global packages

sudo pip3 uninstall virtualenv

Now uninstall the apt package on Debian/Ubuntu (uninstall using your package manager for other distros):

sudo apt purge python3-virtualenv

Now it’s time to install one version of virtualenv:

sudo pip3 install virtualenv

After that, you can try running tox again.

Posted by Uli Köhler in Python

Create a numpy array of one datetime64 per day and mark the start of the month

startdate = np.datetime64('2022-01-01T00:00:00.000000')
 # 10000 days. This array contains 0 (Day 0), 1 (Day 1), etc
day_offsets = np.arange(10000, dtype=np.int64)
usec_per_day = int(1e6) * 86400 # 86.4k sec per day, 1e6 microseconds per second
# Compute microseconds offset from first day
usec_offsets = day_offsets * usec_per_day
# Compute timestamps
timestamps = startdate + usec_offsets

# Mark start of month in boolean array
is_start_of_month = np.zeros_like(timestamps, dtype=bool)
for index, timestamp in np.ndenumerate(timestamps):
    is_start_of_month[index[0]] = timestamp.astype(datetime).day == 1

Using this method, timestamps will be the start of each day

array(['2022-01-01T00:00:00.000000', '2022-01-02T00:00:00.000000',
       '2022-01-03T00:00:00.000000', ..., '2101-12-30T00:00:00.000000',
       '2101-12-31T00:00:00.000000', '2102-01-01T00:00:00.000000'],
      dtype='datetime64[us]')

 

Posted by Uli Köhler in Data science, Python

Pandas: How to apply numpy function to every column

You can use df.transform(func, axis=0) to apply a numpy function. This leverages the fact that numpy functions work with pandas Series objects.

Example based on How to create pandas time series DataFrame example dataset:

# Load pre-built time series example dataset
df = pd.read_csv("https://datasets.techoverflow.net/timeseries-example.csv", parse_dates=["Timestamp"])
df.set_index("Timestamp", inplace=True)

# np.square will be called individually for each column
new_df = df.transform(np.square, axis=0)

Output

Original time series:

Squared time series:

Full example code

import numpy as np
import pandas as pd
from matplotlib import pyplot as plt

# Load pre-built time series example dataset
df = pd.read_csv("https://datasets.techoverflow.net/timeseries-example.csv", parse_dates=["Timestamp"])
df.set_index("Timestamp", inplace=True)

# np.sqrt will be called individually for each column
new_df = df.transform(np.square, axis=0)

# Plot subsection of original DF for better visibility
df.iloc[:len(df)//2].plot()
plt.gcf().set_size_inches(10,5)
plt.savefig("Normal-Timeseries.svg")

# Plot subsection of transformed DF for better visibility
new_df.iloc[:len(df)//2].plot()
plt.gcf().set_size_inches(10,5)
plt.savefig("Square-Timeseries.svg")

 

Posted by Uli Köhler in pandas, Python

Numpy nth root: How to

To find the nth root of number or array x in numpy use:

np.power(x, (1/n))

n can be a natural number like 4 but it can also be a floating point number like 3.26.

Example: Compute the 78th root of 1.234

>>> import numpy as np
>>> np.power(1.234, (1/78))
1.0026992894299456

 

Posted by Uli Köhler in Python