Why the interpreter complains that library named "math" does not exist? - lua

Why the interpreter complains that library named "math" does not exist?
As far as I know, this library is loaded when invoking luaL_newstate on Lua-5.3.5.
#include "lua.hpp"
#include <iostream>
#include <assert.h>
#include <fstream>
int main()
{
struct lua_State *L = luaL_newstate();
int ret;
std::string fileName("co.lua");
if(fileName.empty())
{
std::cout << "the filename is empty" << std::endl;
return -1;
}
std::ifstream fileScript(fileName, fileScript.in|std::ios::ate);
if(!fileScript.is_open())
{
std::cout << "open file failed" << std::endl;
return -2;
}
size_t size = fileScript.tellg();
if(size <= 0)
{
std::cout << "file has no valid content" << std::endl;
return -3;
}
std::string textCont(size, '\0');
fileScript.seekg(0);
fileScript.read(&textCont[0], size);
if((ret=luaL_loadbuffer(L, textCont.data(), textCont.length(), "co.lua")) == LUA_OK)
{
if((ret=lua_pcall(L, 0, LUA_MULTRET, 0)) != LUA_OK)
{
std::cout << "error in invoking lua_pcall():" << ret << std::endl;
if(lua_isstring(L, -1))
{
const char *errMsg = lua_tostring(L, -1);
lua_pop(L, 1);
std::cout << "script run encounter err:" << errMsg << std::endl;
}
}
}
}
Here is the code snippet(it's very simple) for the file named "co.lua":
a = 1;
b=2;
a=a+1;
math.sin(a)
Here is the error message in the console:
error in invoking lua_pcall():2
script run encounter err:[string "co.lua"]:29: attempt to index a nil value (global 'math')

The documentation states that you need to call luaL_openlibs or luaL_requiref which does not seem to be the case with your posted program.
To have access to these libraries, the C host program should call the luaL_openlibs function, which opens all standard libraries.
Alternatively (emphasis mine):
Alternatively, the host program can open them individually by using luaL_requiref to call:
luaopen_base (for the basic library)
luaopen_package (for the package library)
luaopen_coroutine (for the coroutine library)
luaopen_string (for the string library)
luaopen_utf8 (for the UTF8 library)
luaopen_table (for the table library)
luaopen_math (for the mathematical library)
luaopen_io (for the I/O library)
luaopen_os (for the operating system library)
luaopen_debug (for the debug library).
These functions are declared in lualib.h.
So change your program's first few lines to something like below.
You also need to compare the return value from luaL_newstate with NULL and handle that error condition.
int main()
{
struct lua_State *L = luaL_newstate();
if( L == NULL ) {
puts( "Lua failed to initialize." );
exit(1);
}
luaL_openlibs( L );
// etc

Related

Libqmi - glib callback function not getting called

I am new to libqmi and wanted to start by just opening a new device. But the callback function is never getting called and therefore no device object returned.
I running the code on Ubuntu 64 Bit.
On this website: https://developer.gnome.org/gio/stable/GAsyncResult.html
I found how this should be handled and programmed it that way, but it still doesn't work.
#include <iostream>
#include <libqmi-glib/libqmi-glib.h>
#include <gio/gio.h>
using namespace std;
void device_create_start(const char* device_file);
void device_create_stop(GObject* obj, GAsyncResult* res, gpointer data);
int something = 0;
int main()
{
cout << "Start\n";
device_create_start("/dev/cdc-wdm0");
cout << "DEBUG: Something: " << something << "\n";
cout << "Stop\n";
return 0;
}
void device_create_start(const char* device_file)
{
GFile* file = g_file_new_for_path(device_file);
if(file)
{
GCancellable* cancellable = g_cancellable_new();
GAsyncReadyCallback callback = device_create_stop;
gpointer user_data = NULL;
cout << "INFO: qmi_device_new starting!\n";
qmi_device_new(file, cancellable, callback, user_data);
cout << "INFO: qmi_device_new started!\n";
cout << "INFO: Waiting!\n";
usleep(10000);
cout << "INFO: Is cancelled?: " << g_cancellable_is_cancelled(cancellable) << "\n";
cout << "INFO: canceling!\n";
g_cancellable_cancel(cancellable);
cout << "INFO: Waiting again!\n";
usleep(100000);
cout << "INFO: Is cancelled?: " << g_cancellable_is_cancelled(cancellable) << "\n";
something = 1;
}
else
{
cout << "ERROR: Could not create device file!\n";
}
}
void device_create_stop(GObject* obj, GAsyncResult* res, gpointer data)
{
cout << "INFO: device_create_stop\n";
something = 2;
cout << "INFO: qmi_device_new_finish starting\n";
GError *error;
QmiDevice* device = qmi_device_new_finish(res, &error);
cout << "INFO: qmi_device_new_finish started\n";
if(device == NULL)
{
cout << "ERROR: Could not create device!\n";
}
else
{
cout << "INFO: Device created!\n";
//device_open(device);
}
}
When I run this code the output is:
Start
INFO: qmi_device_new starting!
INFO: qmi_device_new started!
INFO: Waiting!
INFO: Is cancelled?: 0
INFO: canceling!
INFO: Waiting again!
INFO: Is cancelled?: 1
DEBUG: Something: 1
Stop
The code in the callback function is never called.
Update 1
I simplified the code and changed some things that I oversaw on the gnome reference site, like a static callback function. But this doesn't work either
#include <iostream>
#include <libqmi-glib/libqmi-glib.h>
#include <gio/gio.h>
#include <glib/gprintf.h>
using namespace std;
void device_create_start(const char* device_file);
static void device_create_stop(GObject* obj, GAsyncResult* res, gpointer data);
int something = 0;
int main()
{
g_printf ("Start\n");
device_create_start("/dev/cdc-wdm0");
cout << "DEBUG: Something: " << something << "\n";
while(true)
{
;
}
cout << "Stop\n";
return 0;
}
void device_create_start(const char* device_file)
{
GFile* file = g_file_new_for_path(device_file);
if(file)
{
cout << "INFO: qmi_device_new starting!\n";
qmi_device_new(file, NULL, device_create_stop, NULL);
cout << "INFO: qmi_device_new started!\n";
something = 1;
}
else
{
cout << "ERROR: Could not create device!\n";
}
}
static void device_create_stop(GObject* obj, GAsyncResult* res, gpointer data)
{
g_printf ("Hurray!\n");
something = 2;
}
The new output:
Start
INFO: qmi_device_new starting!
INFO: qmi_device_new started!
DEBUG: Something: 1
Does anyone has a clue why this is not working?
As Philip said (hey Philip!), you're missing the main loop. The qmi_device_new() function is an method that finishes asynchronously, and once finished, the result of the operation is provided in the callback function you provide. In order for the asynchronous function to even do something, you need to have a GMainLoop running for as long as your program logic runs.

child class of leafsystem generating sinusoidal signal

I am trying to make a child class of LeafSystem whose output is sinusoidal and its derivative.
I wrote the code and try to plot it but signal logger doesn't log correctly.
#include "drake/systems/framework/leaf_system.h"
#include "drake/systems/analysis/simulator.h"
#include "drake/systems/framework/diagram.h"
#include "drake/systems/framework/diagram_builder.h"
#include "drake/systems/primitives/signal_logger.h"
#include "drake/common/proto/call_python.h"
class Sinusoid : public drake::systems::LeafSystem<double>
{
public:
Sinusoid (double tstart, double freq, double amp, double offset) :
m_freq(freq), m_amp(amp), m_offset(offset), m_tstart(tstart) {
this->DeclareVectorOutputPort(
drake::systems::BasicVector<double>(2), &Sinusoid::output);
}
private:
void output(const drake::systems::Context<double>& c, drake::systems::BasicVector<double>* output) const {
double t(c.get_time());
double tknot(t - m_tstart);
if (t > m_tstart) {
output->SetAtIndex(0, std::sin(tknot*m_freq + m_offset)*m_amp);
output->SetAtIndex(1, std::cos(tknot*m_freq + m_offset)*m_amp*m_freq);
} else {
output->SetAtIndex(0, 0.0);
output->SetAtIndex(1, 0.0);
}
}
double m_freq{0.0}, m_amp{0.0}, m_offset{0.0}, m_tstart{0.0};
};
int main(int argc, char *argv[])
{
// Add System and Connect
drake::systems::DiagramBuilder<double> builder;
auto system = builder.AddSystem<Sinusoid>(1.0, 2.*M_PI*1., 3., 0.);
auto logger = LogOutput(system->get_output_port(0), &builder);
auto diagram = builder.Build();
// Construct Simulator
drake::systems::Simulator<double> simulator(*diagram);
// Run simulation
simulator.StepTo(100);
// Plot with Python
auto sample_time = logger->sample_times();
auto sample_data = logger->data();
std::cout << sample_time.size() << std::endl;
for (int i = 0; i < sample_time.size(); ++i) {
std::cout << sample_time(i) << " : " << sample_data(i, 0) << " " << sample_data(i, 1) << std::endl;
}
std::cout << "END" << std::endl;
return 0;
}
The output of the code is
2
0 : 0 0
0 : 0 0
END
Whatever number I used in StepTo function, signal logger only cate 2 data whose sampled times are both 0.
The code looks good. Note that TrajectorySource does this almost exactly (and used SingleOutputVectorSource as a base class, which you might consider, too). The only problem is that you do not have anything telling the simulator that there is a reason to evaluate the output port. The logger block will pull on that for every publish event, but you haven't told the simulator to publish.
The solution is to call
simulator.set_publish_every_timestep(true)
http://drake.mit.edu/doxygen_cxx/classdrake_1_1systems_1_1_simulator.html#aef1dc6aeb821503379ab1dd8c6044562
If you want to further control the timestep of the integrator, you could set the parameters of the integrator (e.g. simalator.get_integerator), then calls like set_fixed_step_mode.

Alternative to waitKey() for updating window in OpenCV

All examples and books I've seen so far recommends using waitKey(1) to force repaint OpenCV window. That looks weird and too hacky. Why wait for even 1ms when you don't have to?
Are there any alternatives? I tried cv::updateWindow but it seems to require OpenGL and therefore crashes. I'm using VC++ on Windows.
I looked in to source and as #Dan Masek said, there doesn't seem to be any other functions to process windows message. So I ended up writing my own little DoEvents() function for VC++. Below is the full source code that uses OpenCV to display video frame by frame while skipping desired number of frames.
#include <windows.h>
#include <iostream>
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace std;
bool DoEvents();
int main(int argc, char *argv[])
{
VideoCapture cap(argv[1]);
if (!cap.isOpened())
return -1;
namedWindow("tree", CV_GUI_EXPANDED | CV_WINDOW_AUTOSIZE);
double frnb(cap.get(CV_CAP_PROP_FRAME_COUNT));
std::cout << "frame count = " << frnb << endl;
for (double fIdx = 0; fIdx < frnb; fIdx += 50) {
Mat frame;
cap.set(CV_CAP_PROP_POS_FRAMES, fIdx);
bool success = cap.read(frame);
if (!success) {
cout << "Cannot read frame " << endl;
break;
}
imshow("tree", frame);
if (!DoEvents())
return 0;
}
return 0;
}
bool DoEvents()
{
MSG msg;
BOOL result;
while (::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
result = ::GetMessage(&msg, NULL, 0, 0);
if (result == 0) // WM_QUIT
{
::PostQuitMessage(msg.wParam);
return false;
}
else if (result == -1)
return true; //error occured
else
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
return true;
}

"require" not work in embeded lua

in this code i load and run test.lua file
int main (){
L = luaL_newstate();
luaL_openlibs(L);
luaL_dofile(L, "test.lua");
lua_close(L);
return 0;
}
my test.lua file contents
print ("s1");
r=require 'simple';
print ("s2");
the simple module is installed before
when run ./lua_c ; output is only: s1
but when run lua test.lua; output is
s1
s2
and r in't nil
simple is failing to load or parse or execute. To find problem, use luaL_loadfile instead of luaL_dofile and check the return value. If non zero, there was a load error, which you can pop off the Lua stack and print. If no error, do the lua_pcall(L, 0, LUA_MULTRET, 0)) to run the chuck created by loadfile, and again check return code for error, pop off stack and print. It would be somehting like this:
int main ()
{
L = luaL_newstate();
luaL_openlibs(L);
if (luaL_loadfile(L, "test.lua"))
{
cout << "Error: " << lua_tostring(L, -1) << endl;
}
else if (lua_pcall(L, 0, LUA_MULTRET, 0))
{
cout << "Error: " << lua_tostring(L, -1) << endl;
}
else
{
// call successful
}
lua_close(L);
return 0;
}
Update: now that you know from the error message that simple.so has undefined symbol: lua_gettop, you know that there is a link error. Perhaps simple.so isn't linked to lua51.so, but since it works from lua.exe, which is linked to lua lib, one would it would work from your app, which is surely linked to it too. Another possibility is that lua.exe is statically linked but simple.so is not linked. Verify that simple.so is linked to lua51.so and that the lib it links to can be found such as via LD_LIBRARY_PATH. Verify lua.exe is linked to same .so.

After reading multiple frames from a camera, OpenCV suddenly always fails to read frames. How do I diagnose this?

I run a program similar to the one in this question: https://stackoverflow.com/a/8719192/26070
#include <opencv/highgui.h>
#include <iostream>
/** #function main */
int main( int argc, char** argv )
{
cv::VideoCapture vcap;
cv::Mat image;
const std::string videoStreamAddress = "rtsp://192.0.0.1:8081/live.sdp";
//open the video stream and make sure it's opened
if(!vcap.open(videoStreamAddress)) {
std::cout << "Error opening video stream or file" << std::endl;
return -1;
}
for(;;) {
if(!vcap.read(image)) {
std::cout << "No frame" << std::endl;
cv::waitKey(500);
} else {
cv::imshow("Output Window", image);
}
if(cv::waitKey(1) >= 0) break;
}
}
The program runs fine for a certain amount of time (about one minute or so) and then the call to read() (method from cv::VideoCapture) always returns false.
The output is as follows:
[mpeg4 # 00da27a0] ac-tex damaged at 22 7
[mpeg4 # 00da27a0] Error at MB: 309
No frame
No frame
No frame
Note: the first two lines are not always present.
So, how can I determine what the root of the problem is?

Resources