In TestGroup_Person, when I retrieve a QSharedPointer<-JB_TableRowProt> from JB_PersonDao and assign it to QSharedPointer<-JB_TableRowProt> aGroup_Person (in .h), I then get this error in the methods of TestGroup_Person.
Alternatively, if I retrieve a QSharedPointer<-JB_TableRowProt> from JB_DaoProt in each method (and don't assign it to QSharedPointer<-JB_TableRowProt> aGroup_Person), it works fine.
Can someone explain to me why this assignment appears to be causing the error please?
I got this error:
QFATAL : TestGroup_Person::test_getDBTable_Name() Received signal 11
Function time: 0ms Total time: 0ms
FAIL! : TestGroup_Person::test_getDBTable_Name() Received a fatal error.
Here's the code:
main:
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QStringList arguments = QCoreApplication::arguments();
QFile aFile(DATABASE_FILENAME); // remove existing SP3.db
if (aFile.exists())
aFile.remove();
map<QString, unique_ptr<QObject>> tests;
tests.emplace("group_person", make_unique<TestGroup_Person>());
if (arguments.size() >= 3 && arguments[1] == "-select") {
QString testName = arguments[2];
auto iter = tests.begin();
while(iter != tests.end()) {
if (iter->first != testName) {
iter = tests.erase(iter);
} else {
++iter;
}
}
arguments.removeOne("-select");
arguments.removeOne(testName);
}
int status = 0;
for(auto& test : tests) {
status |= QTest::qExec(test.second.get(), arguments);
}
return status;
}
TestGroup_Person.h
#include <QString>
#include <QtTest>
#include <QSharedPointer>
#include "A_DB_Classes/JB_DatabaseManager.h"
#include "A_Tables/JB_Group_Person.h"
class TestGroup_Person : public QObject
{
Q_OBJECT
public:
TestGroup_Person();
private Q_SLOTS:
void test_allFieldsEqualsFieldNames();
void test_getDBTable_FieldNames();
void test_getDBTable_Name();
void test_hasJoinTable();
void test_setValueForField();
void test_setStorageValueForField();
void test_getStorageFields();
private:
JB_DatabaseManager& mDB;
QSharedPointer<JB_TableRowProt> aGroup_Person;
};
TestGroup_Person.cpp:
TestGroup_Person::TestGroup_Person():
mDB(JB_DatabaseManager::instance())
{
aGroup_Person = mDB.aPersonDao.getJoinTableObject();
}
void TestGroup_Person::test_allFieldsEqualsFieldNames()
{
const QVector<QString>& aVector = aGroup_Person->getDBTable_FieldNames();
const QList<QString> aList = aGroup_Person->getAllFieldNames();
bool isThere = true;
QString fieldName = "";
QString aResult = "This field name does not exist in all_FieldNamesAndValuesH";
for (int i = 0; i < aVector.size() && isThere; ++i) {
fieldName = aVector.at(i);
isThere = aList.contains(aVector.at(i));
}
if (isThere)
aResult = fieldName;
QCOMPARE(fieldName, QString(aResult));
}
void TestGroup_Person::test_getDBTable_FieldNames()
{
const QVector<QString>& aVector = aGroup_Person->getDBTable_FieldNames();
QString fieldName = "";
for (int i = 0; i < aVector.size(); ++i) {
fieldName = fieldName + aVector.at(i) +",";
}
QVector<QString> fieldNames;
QVector<QString> columnHeadings;
aGroup_Person->getViewableFieldNamesAndHeadings(fieldNames, columnHeadings);
bool correct = fieldNames.count() == columnHeadings.count();
if (!correct)
correct = columnHeadings.count() == 0;
QCOMPARE(correct, true);
QCOMPARE(fieldName, QString("groupID,personID,jobID,grp_per_dateTimeStamp,"));
}
void TestGroup_Person::test_getDBTable_Name()
{
QCOMPARE(aGroup_Person->getDBTable_Name(), QString("Group_Person"));
}
Relevant method of JB_DaoProt:
QSharedPointer<JB_TableRowProt> JB_DaoProt::getJoinTableObject()
{
JB_TableRowProt* aJoinTable = new_JoinTableRowProt();
QSharedPointer<JB_TableRowProt> pJoinTable(aJoinTable);
return pJoinTable;
}
Related
I am trying to integrate the Glib main loop into the libev event loop. Actually, I am using their C++ wrappers: glibmm [1] and ev++ [2]. The main idea was taken from the EV::Glib Perl module [3]. However, my implementation sometimes hangs when I try to perform some async task (e.g., reading a text file from the filesystem):
#include <ev++.h>
#include <giomm.h>
#include <glibmm.h>
struct context;
int to_ev_events(Glib::IOCondition events) {
int result = EV_NONE;
if ((events & Glib::IOCondition::IO_IN) != Glib::IOCondition{})
result |= EV_READ;
if ((events & Glib::IOCondition::IO_OUT) != Glib::IOCondition{})
result |= EV_WRITE;
return result;
}
Glib::IOCondition to_glib_events(int events) {
Glib::IOCondition result{};
if ((events & EV_READ) != EV_NONE) result |= Glib::IOCondition::IO_IN;
if ((events & EV_WRITE) != EV_NONE) result |= Glib::IOCondition::IO_OUT;
return result;
}
struct prepare_watcher {
prepare_watcher(context &c) : ctx{c} {
watcher.priority = EV_MINPRI;
watcher.set(this);
watcher.start();
}
void operator()(ev::prepare &watcher, int revents);
ev::prepare watcher;
context &ctx;
};
struct check_watcher {
check_watcher(context &c) : ctx{c} {
watcher.priority = EV_MAXPRI;
watcher.set(this);
watcher.start();
}
void operator()(ev::check &watcher, int revents);
ev::check watcher;
context &ctx;
};
struct timer_watcher {
timer_watcher() { watcher.priority = EV_MINPRI; }
ev::timer watcher;
};
struct io_watcher {
io_watcher(int fd, int events) {
watcher.priority = EV_MINPRI;
watcher.start(fd, events);
}
ev::io watcher;
};
struct context {
Glib::RefPtr<Glib::MainContext> context = Glib::MainContext::get_default();
ev::default_loop loop;
std::vector<Glib::PollFD> poll_fds;
int priority{};
prepare_watcher prepare{*this};
check_watcher check{*this};
timer_watcher timer;
std::map<int, io_watcher> ios;
};
void prepare_watcher::operator()(ev::prepare &watcher, int revents) {
ctx.context->dispatch();
ctx.context->prepare(ctx.priority);
ctx.poll_fds.clear();
int timeout = 0;
ctx.context->query(ctx.priority, timeout, ctx.poll_fds);
for (Glib::PollFD &poll_fd : ctx.poll_fds) {
int fd = poll_fd.get_fd();
ctx.ios.try_emplace(fd, fd, to_ev_events(poll_fd.get_events()));
}
if (timeout >= 0) ctx.timer.watcher.start(timeout * 1e-3);
}
void check_watcher::operator()(ev::check &watcher, int revents) {
for (Glib::PollFD &poll_fd : ctx.poll_fds) {
int fd = poll_fd.get_fd();
io_watcher &io = ctx.ios.at(fd);
if (io.watcher.is_pending())
poll_fd.set_revents(
to_glib_events(ev_clear_pending(ctx.loop.raw_loop, &io.watcher)));
ctx.ios.erase(fd);
}
if (ctx.timer.watcher.is_active() || ctx.timer.watcher.is_pending())
ctx.timer.watcher.stop();
ctx.context->check(ctx.priority, ctx.poll_fds);
}
int main() {
Gio::init();
context ctx;
Glib::RefPtr<Gio::File> file = Gio::File::create_for_path("file.txt");
file->read_async([&](Glib::RefPtr<Gio::AsyncResult> result) {
file->read_finish(result);
ctx.loop.break_loop(ev::ALL);
});
ctx.loop.run();
}
Any ideas?
[1] https://github.com/GNOME/glibmm
[2] http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#C_API-2
[3] https://github.com/gitpan/EV-Glib/blob/master/Glib.xs
I want to manipulate my robot arm (UR5e) to perform pick & place task
so I use ROS and Moveit on Ubuntu 18.04 and I refer to Moveit tutorials (link below)
https://github.com/ros-planning/moveit_tutorials/blob/melodic-devel/doc/move_group_interface/src/move_group_interface_tutorial.cpp
And this is part of my code
const std::vector<double> CAMERA_JOINT = {-1.57899937, -1.63659524, -1.02328654, -2.0525072, 1.57446152, 0.0};
const std::vector<double> HOME_JOINT = {-3.14159265, -1.01839962, -1.43169359, -2.26212124, 1.57376339, 0.0};
class MyRobotPlanning
{
private:
const std::string PLANNING_GROUP = "manipulator";
const robot_state::JointModelGroup* joint_model_group;
moveit::planning_interface::MoveGroupInterface move_group;
moveit::planning_interface::MoveGroupInterface::Plan my_plan;
public:
MyRobotPlanning(): move_group(PLANNING_GROUP)
{
move_group.allowReplanning(true);
move_group.setNumPlanningAttempts(10);
}
void goToGoalPose(geometry_msgs::Pose &pose);
void goToJointState(std::vector<double> setting_values);
};
bool robotMove(capston::FeedBack::Request &req,
capston::FeedBack::Response &res)
{
MyRobotPlanning UR;
cout << "ready to sort your tools!!" << endl;
if (req.next_action == 1)
{
UR.goToJointState(CAMERA_JOINT);
res.feed_back = true;
return true;
}
else if(req.next_action == 2)
{
ros::NodeHandle nh;
ros::ServiceClient client = nh.serviceClient<capston::GraspPose>("grasppose");
capston::GraspPose g_pose;
if (client.call(g_pose))
{
geometry_msgs::Pose goal_pose;
goal_pose.position.x = g_pose.response.grasp_pose.position.x;
goal_pose.position.y = g_pose.response.grasp_pose.position.y;
goal_pose.position.z = g_pose.response.grasp_pose.position.z;
goal_pose.orientation.w = 1.0;
UR.goToGoalPose(goal_pose);
ROS_INFO("Tool Number: %d", (int)g_pose.response.tool_number);
ROS_INFO("tool_pose: [%f, %f, %f]", g_pose.response.grasp_pose.position.x,
g_pose.response.grasp_pose.position.y,
g_pose.response.grasp_pose.position.z);
return true;
}
else
{
ROS_ERROR("Failed to call service");
return false;
}
}
cout << "This code is not complete";
return true;
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "action_part");
ros::NodeHandle nh;
ros::AsyncSpinner spinner(1);
spinner.start();
ros::ServiceServer server = nh.advertiseService("feedback", robotMove);
ROS_INFO("Ready srv server!!!");
ros::spin();
return 0;
}
void MyRobotPlanning::goToGoalPose(geometry_msgs::Pose &pose)
{
move_group.setPoseTarget(pose);
ros::Duration(0.5).sleep();
move_group.move();
}
void MyRobotPlanning::goToJointState(std::vector<double> setting_values)
{
move_group.setJointValueTarget(setting_values);
ros::Duration(0.5).sleep();
move_group.move();
}
This is both server and client node
so it receives xyz coordinates of the object (that we want to grasp) from another node
and also receive next_action from the other node and then move my UR5e
When it receives the service feedback.request.next_action = 1 so it calls MyRobotPlanning::goToJointState function and my UR5e moves to CAMERA_JOINT position successfully but it doesn't progress any more
I think there's something stuck in move_group.move() but I don't know why
How to block program execution until callback function complete execution ?
From my main() i launch interface.getImage(); function who want to get images from our database. When we receive images the callback function void InterfaceColliseo::dataReceived (std::shared_ptr data) start to execute.
But I have a problem my program main() terminate before my callback function execution ?
main.cpp
int main(){
InterfaceColliseo interface;
IMAGE = true;
interface.getImage();
// want to block program here
return 0;
}
callback function
void InterfaceColliseo::dataReceived (std::shared_ptr<IData> data)
{
if (!data->isValid())
return;
const unsigned char* twoDImageData = data->get2DImageData();
int width2DImageData = data->getWidth2DImageData();
int height2DImageData = data->getHeight2DImageData();
const unsigned char* disparityData = data->getDisparityData();
int widthDisparityData = data->getWidthDisparityData();
int heightDisparityData = data->getHeightDisparityData();
if(IMAGE) {
saveImage(twoDImageData, width2DImageData, height2DImageData,
disparityData, widthDisparityData, heightDisparityData);
IMAGE = false;
}
if(ACQUISATION){
QList<GstObservationBasic> detectorData = data->getObstaclesData();
getObstacles(detectorData);
}
}
I think you just can use thread from std. When you use join, the main thread will wait until joined thread will finish his job.
#include <thread>
//in main
std::thread myThread(interface.getImage);
myThread.join();
#include "interface_colliseo.h"
std::mutex mtx;
std::condition_variable cv;
bool IMAGE;
bool ACQUISATION;
InterfaceColliseo::InterfaceColliseo(){
}
void InterfaceColliseo::startStreaming(){
dataReceiver = _device->getDataReceiver();
start();
}
void InterfaceColliseo::getImage(){
dataReceiver = _device->getDataReceiver();
start();
}
InterfaceColliseo::InterfaceColliseo(QString IP): _IP(IP) {
qDebug() << "INDUS-5: IP server: " << _IP;
qDebug() << "INDUS-5: Connecting to sensor...";
_colliseoClient.setIPServer(_IP);
}
bool InterfaceColliseo::connect2UT(){
QString path = qApp->applicationDirPath()+"/Configuration.ini";
QSettings config(path, QSettings::IniFormat);
_IP = config.value("Connection/IP","10.0.3.144").toString();
_colliseoClient.setIPServer(_IP);
_device = _colliseoClient.getDevice();
_device->connectSensor();
bool connect = _device->isConnected();
return connect;
}
QString InterfaceColliseo::sensorName(){
return _device->getDeviceDiagnostics()->getOperatingData()
->getDeviceInformation()->getOrderNumber();
}
QString InterfaceColliseo::sensorFirmwareVersion(){
return _device->getDeviceDiagnostics()->getOperatingData()
->getDeviceInformation()->getFirmwareVersion();
}
QString InterfaceColliseo::getSensorHeadPN(QString sensor){
return _device->getDeviceDiagnostics()->getOperatingData()
->getDeviceInformation()->getSensorHeadPN(sensor);
}
QString InterfaceColliseo::getEvaluationUnitSN(){
return _device->getDeviceDiagnostics()->getOperatingData()
->getDeviceInformation()->getEvaluationUnitSN();
}
QString InterfaceColliseo::getEvaluationUnitPN(){
return _device->getDeviceDiagnostics()->getOperatingData()
->getDeviceInformation()->getEvaluationUnitPN();
}
QString InterfaceColliseo::getEvaluationUnitFirmwareVersion(){
return _device->getDeviceDiagnostics()->getOperatingData()
->getDeviceInformation()->getEvaluationUnitFirmwareVersion();
}
QString InterfaceColliseo::getEstimatedAngleX(){
return _device->getDeviceDiagnostics()->getOperatingData()
->getDeviceInformation()->getEstimatedAngleX();
}
QString InterfaceColliseo::getEstimatedAngleZ(){
return _device->getDeviceDiagnostics()->getOperatingData()
->getDeviceInformation()->getEstimatedAngleZ();
}
QString InterfaceColliseo::getEstimatedHeight(){
return _device->getDeviceDiagnostics()->getOperatingData()
->getDeviceInformation()->getEstimatedHeight();
}
void InterfaceColliseo::saveImage(const unsigned char*twoDImageData,
int width2DImageData, int height2DImageData,
const unsigned char*disparityData,
int widthDisparityData, int disptHeight){
Configuration configuration;
QString logFolder = configuration.getLogFolder();
QImage imgRight(twoDImageData, width2DImageData, height2DImageData, QImage::Format_Indexed8);
QImage imgDisparity(disparityData, widthDisparityData, disptHeight, QImage::Format_Indexed8);
QPixmap imgRght = QPixmap::fromImage(imgRight);
QPixmap imgDisp = QPixmap::fromImage(imgDisparity);
QString rghtImgPath = logFolder + "raw_image.png";
QString dispImgPath = logFolder + "disp_image.png";
imgRght.save(rghtImgPath, "PNG");
imgDisp.save(dispImgPath, "PNG");
}
void InterfaceColliseo::getObstacles(QList<GstObservationBasic> detectorData){
if (detectorData.size() == 0)
{
qDebug() << "Obstacles: no detected obstacles.";
return;
}
Configuration config;
config.writeLog("***************Obstacles List Acquisation******************");
Q_FOREACH(const GstObservationBasic &obs, detectorData)
{
qDebug() << "Obstacles: " << gstObservationToString(obs);
config.writeLog(gstObservationToString(obs));
}
}
void InterfaceColliseo::dataReceived (std::shared_ptr<IData> data)
{
if (!data->isValid())
return;
const unsigned char* twoDImageData = data->get2DImageData();
int width2DImageData = data->getWidth2DImageData();
int height2DImageData = data->getHeight2DImageData();
const unsigned char* disparityData = data->getDisparityData();
int widthDisparityData = data->getWidthDisparityData();
int heightDisparityData = data->getHeightDisparityData();
if(IMAGE) {
saveImage(twoDImageData, width2DImageData, height2DImageData,
disparityData, widthDisparityData, heightDisparityData);
IMAGE = false;
}
if(ACQUISATION){
QList<GstObservationBasic> detectorData = data->getObstaclesData();
getObstacles(detectorData);
ACQUISATION = false;
}
}
void InterfaceColliseo::start() {
dataReceiver->addListener(this);
if(dataReceiver->isListening())
dataReceiver->stopListening();
dataReceiver->startListening();
_device->triggerSingleImageAcquisition();
}
I'd like to save custom class to XML using QSettings. But I always get XML without structure members.
#include <QCoreApplication>
#include <QtCore/qdatastream.h>
#include <qxmlstream.h>
#include <qdebug.h>
#include <QtCore/QSettings>
#include <QMetaType>
struct Interface_struct
{
QString name;
QString ip;
};
Q_DECLARE_METATYPE(Interface_struct)
QDataStream& operator <<(QDataStream& out, const Interface_struct& s)
{
out << s.name << s.ip;
return out;
}
QDataStream& operator >>(QDataStream& in, Interface_struct& s)
{
in >> s.name;
in >> s.ip;
return in;
}
static bool readXmlFile(QIODevice &device, QSettings::SettingsMap &map)
{
qDebug()<< "read";
QXmlStreamReader reader(&device);
QString key;
while(!reader.atEnd())
{
reader.readNext();
if( reader.isStartElement() && reader.tokenString() != "Settings")
{
if( reader.text().isNull() )
{
// key = Settings
if(key.isEmpty())
{
key = reader.tokenString();
}
// key = Settings/Intervall
else
{
key += "/" + reader.tokenString();
}
}
else
{
map.insert(key, reader.text().data());
}
}
}
return true;
}
static bool writeXmlFile(QIODevice &device, const QSettings::SettingsMap &map)
{
qDebug()<< "write";
QXmlStreamWriter writer(&device);
writer.writeStartDocument("1.0");
writer.writeStartElement("Settings");
foreach(QString key, map.keys())
{
foreach(QString elementKey, key.split("/"))
{
writer.writeStartElement(elementKey);
}
writer.writeCharacters(map.value(key).toString());
writer.writeEndElement();
}
writer.writeEndElement();
writer.writeEndDocument();
return true;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qRegisterMetaType<Interface_struct>("Interface_struct");
qRegisterMetaTypeStreamOperators<Interface_struct>("Interface_struct");
{
Interface_struct s;
s.name = QString("br03000");
s.ip = QString("172.16.222.5");
const QSettings::Format xml_format =
QSettings::registerFormat("xml", readXmlFile, writeXmlFile);
if(xml_format == QSettings::InvalidFormat)
{
qDebug() << "InvalidFormat!";
return 0;
}
QSettings::setPath(xml_format, QSettings::UserScope, "/home/farit/test/");
QSettings settings(xml_format, QSettings::UserScope, "xml_cfg");
settings.setValue("network", QVariant::fromValue(s));
}
{
QSettings::Format xml_format =
QSettings::registerFormat("xml", readXmlFile, writeXmlFile);
QSettings::setPath(xml_format, QSettings::UserScope, "/home/farit/test/");
QSettings settings(xml_format, QSettings::UserScope, "xml_cfg");
QVariant value = settings.value("network");
Interface_struct interface = value.value<Interface_struct>();
qDebug() << "TEST: " << interface.name << interface.ip;
}
return 0;
}
I get this output:
read
write
read
TEST: "" ""
Press <RETURN> to close this window...
And XML looks like this:
<?xml version="1.0" encoding="UTF-8"?><Settings><network></network></Settings>
How can I save structure members of custom class to XML using QSettings?
UPDATE: I'm sorry, I forgot to mention, that is supposed to be done in Qt4.
I have a class server for which I have created a signal joined(QString name). I call it in a function called join(QString name), however I'm getting the error
Server.o: In function Server::join(QString)':
Server.cpp:(.text+0x48): undefined reference to
Server::joined(QString)' collect2: ld returned 1 exit status
This is what my header file looks like:
#ifndef SERVER_H
#define SERVER_H
#include <QString>
#include <mqueue.h>
#include <QVector>
#include <QStringList>
#include "../src/messages.h"
class Server
{
public:
Server();
void start();
private:
void join(QString name);
char buf[MSG_SIZE], msgSend[MSG_SIZE];
QVector<mqd_t> mq_external;
QVector<QString> users;
mqd_t mq_central;
struct mq_attr attr;
signals:
void joined(QString name);
};
#endif // SERVER_H
and this is my cpp file:
#include "Server.h"
using namespace std;
Server::Server()
{
}
void Server::start(){
attr.mq_maxmsg = 100;
attr.mq_msgsize = MSG_SIZE;
attr.mq_flags = 0;
mq_unlink(CENTRALBOX);
mq_central = mq_open(CENTRALBOX, O_RDONLY | O_CREAT, S_IRWXU, &attr);
while(1)
{
int tempMsgVal = mq_receive(mq_central, buf, MSG_SIZE, 0);
if(tempMsgVal != -1){
QString tempS = buf;
QStringList tempSL = tempS.split(":");
if(tempSL.size() == 2 && tempSL.at(0) == "started")
{
int x = 0;
bool exists = false;
for(int i = 0; i < mq_external.size(); i++)
{
x = QString::compare(tempSL[1], users.at(i), Qt::CaseInsensitive);
if(x == 0)
{
exists = true;
break;
}
}
if(!exists)
{
sprintf(buf,"joined");
QString tempS1 = tempSL[1] + "new";
QByteArray byteArray = tempS1.toUtf8();
const char* tempr = byteArray.constData();
mqd_t tempMQ = mq_open(tempr, O_RDWR);
int tempI = mq_send(tempMQ, buf, strlen(buf), 0);
}
else
{
sprintf(buf,"invalidname");
QString tempS1 = tempSL[1] + "new";
QByteArray byteArray = tempS1.toUtf8();
const char* tempr = byteArray.constData();
mqd_t tempMQ = mq_open(tempr, O_RDWR);
int tempI = mq_send(tempMQ, buf, strlen(buf), 0);
}//Endelse
}//Endif
}//Endif
}//Endwhile
}
void Server::join(QString name)
{
emit joined(name);
}
At the beginning of your class declaration you should have the macro Q_OBJECT and be sure to inherit from some QObject descendant.
Apart from whatever is mentioned in this answer, also make sure to:
click 'Build' option > Run 'qmake'
That should fix the pending errors as well.