Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Geomagic] Fix dll export and some enhancements #786

Merged
merged 7 commits into from
Oct 4, 2018
3 changes: 3 additions & 0 deletions applications/plugins/Geomagic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ endif()
set(HEADER_FILES
src/GeomagicDriver.h
src/initPlugin.h
src/config.h
)

set(SOURCE_FILES
Expand All @@ -26,7 +27,9 @@ include_directories( ${OPENHAPTICS_INCLUDE_DIR})

add_library(${PROJECT_NAME} SHARED ${HEADER_FILES} ${SOURCE_FILES} ${SCENES_FILES} ${README_FILES})
set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "-DPLUGIN_DATA_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}/\"")
set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "-DSOFA_BUILD_GEOMAGIC")
target_link_libraries(${PROJECT_NAME} SofaHelper SofaUserInteraction ${OPENHAPTICS_LIBRARIES})
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/..")

if(NOT ${SOFA_NO_OPENGL})
target_link_libraries(${PROJECT_NAME} SofaOpenglVisual)
Expand Down
178 changes: 117 additions & 61 deletions applications/plugins/Geomagic/src/GeomagicDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,12 @@

#include "GeomagicDriver.h"
#include <sofa/core/ObjectFactory.h>
//#include <sofa/core/objectmodel/HapticDeviceEvent.h>
#include <sofa/simulation/AnimateBeginEvent.h>
#include <sofa/simulation/AnimateEndEvent.h>
#include <sofa/simulation/Node.h>
#include <sofa/simulation/MechanicalVisitor.h>
#include <sofa/simulation/UpdateMappingVisitor.h>
#include <sofa/core/objectmodel/KeypressedEvent.h>
#include <sofa/core/objectmodel/KeyreleasedEvent.h>
#include <sofa/core/objectmodel/ScriptEvent.h>
#include <sofa/core/objectmodel/MouseEvent.h>
#include <sofa/helper/system/thread/CTime.h>
#include <sofa/core/visual/VisualParams.h>
Expand Down Expand Up @@ -189,9 +187,12 @@ GeomagicDriver::GeomagicDriver()
, d_posDevice(initData(&d_posDevice, "positionDevice", "position of the base of the part of the device"))
, d_button_1(initData(&d_button_1,"button1","Button state 1"))
, d_button_2(initData(&d_button_2,"button2","Button state 2"))
, d_emitButtonEvent(initData(&d_emitButtonEvent, false, "emitButtonEvent", "If true, will send event through the graph when button are pushed/released"))
, d_inputForceFeedback(initData(&d_inputForceFeedback, Vec3d(0,0,0), "inputForceFeedback","Input force feedback in case of no LCPForceFeedback is found (manual setting)"))
, d_maxInputForceFeedback(initData(&d_maxInputForceFeedback, double(1.0), "maxInputForceFeedback","Maximum value of the normed input force feedback for device security"))
, d_manualStart(initData(&d_manualStart, false, "manualStart", "If true, will not automatically initDevice at component init phase."))
, m_simulationStarted(false)
, m_errorDevice(0)
{
this->f_listening.setValue(true);
m_forceFeedback = NULL;
Expand All @@ -200,10 +201,13 @@ GeomagicDriver::GeomagicDriver()
GeomagicDriver::~GeomagicDriver()
{
hdMakeCurrentDevice(m_hHD);

if (!m_hStateHandles.empty()) {
hdStopScheduler();
}

hdStopScheduler();

for (std::vector< HDCallbackCode >::iterator i = m_hStateHandles.begin();
for (std::vector< HDSchedulerHandle >::iterator i = m_hStateHandles.begin();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for(HDSchedulerHandle : m_hStateHandles){}
:)

i != m_hStateHandles.end(); ++i)
{
hdUnschedule(*i);
Expand All @@ -215,9 +219,27 @@ GeomagicDriver::~GeomagicDriver()

//executed once at the start of Sofa, initialization of all variables excepts haptics-related ones
void GeomagicDriver::init()
{

}

void GeomagicDriver::bwdInit()
{
if(m_errorDevice != 0)
return;

simulation::Node *context = dynamic_cast<simulation::Node *>(this->getContext()); // access to current node
m_forceFeedback = context->get<ForceFeedback>(this->getTags(), sofa::core::objectmodel::BaseContext::SearchRoot);

if (d_manualStart.getValue() == false)
initDevice();
}


void GeomagicDriver::initDevice()
{
m_initVisuDone = false;
m_errorDevice = false;
m_errorDevice = 0;
HDErrorInfo error;

HDSchedulerHandle hStateHandle = HD_INVALID_HANDLE;
Expand All @@ -227,7 +249,7 @@ void GeomagicDriver::init()
{
msg_error() << "Failed to initialize the device called " << d_deviceName.getValue().c_str();
d_omniVisu.setValue(false);
m_errorDevice = true;
m_errorDevice = error.errorCode;
//init the positionDevice data to avoid any crash in the scene
m_posDeviceVisu.clear();
m_posDeviceVisu.resize(1);
Expand All @@ -246,58 +268,73 @@ void GeomagicDriver::init()
if (HD_DEVICE_ERROR(error = hdGetError()))
{
printError(&error, "Error with the device Default PHANToM");
m_errorDevice = true;
m_errorDevice = error.errorCode;
return;
}

if(d_maxInputForceFeedback.isSet())
if (d_maxInputForceFeedback.isSet())
{
msg_info() << "maxInputForceFeedback value ("<< d_maxInputForceFeedback.getValue() <<") is set, carefully set the max force regarding your haptic device";
msg_info() << "maxInputForceFeedback value (" << d_maxInputForceFeedback.getValue() << ") is set, carefully set the max force regarding your haptic device";

if(d_maxInputForceFeedback.getValue() <= 0.0)
if (d_maxInputForceFeedback.getValue() <= 0.0)
{
msg_error() << "maxInputForceFeedback value ("<< d_maxInputForceFeedback.getValue() <<") is negative or 0, it should be strictly positive";
msg_error() << "maxInputForceFeedback value (" << d_maxInputForceFeedback.getValue() << ") is negative or 0, it should be strictly positive";
d_maxInputForceFeedback.setValue(0.0);
}
}

reinit();

hdStartScheduler();

if (HD_DEVICE_ERROR(error = hdGetError()))
{
msg_info() << "Failed to start the scheduler";
m_errorDevice = error.errorCode;
if (m_hStateHandles.size()) m_hStateHandles[0] = HD_INVALID_HANDLE;
return;
}
updatePosition();


if (!d_omniVisu.getValue())
return;

//Initialization of the visual components
//resize vectors
m_posDeviceVisu.resize(NVISUALNODE+1);
m_posDeviceVisu.resize(NVISUALNODE + 1);

m_visuActive = false;

for(int i=0; i<NVISUALNODE; i++)
for (int i = 0; i<NVISUALNODE; i++)
{
visualNode[i].visu = NULL;
visualNode[i].mapping = NULL;
}

//create a specific node containing rigid position for visual models
sofa::simulation::Node::SPtr rootContext = static_cast<simulation::Node*>(this->getContext()->getRootContext());
m_omniVisualNode = rootContext->createChild("omniVisu "+d_deviceName.getValue());
m_omniVisualNode = rootContext->createChild("omniVisu " + d_deviceName.getValue());
m_omniVisualNode->updateContext();

rigidDOF = sofa::core::objectmodel::New<component::container::MechanicalObject<sofa::defaulttype::Rigid3dTypes> >();
m_omniVisualNode->addObject(rigidDOF);
rigidDOF->name.setValue("rigidDOF");

VecCoord& posDOF =*(rigidDOF->x.beginEdit());
posDOF.resize(NVISUALNODE+1);
VecCoord& posDOF = *(rigidDOF->x.beginEdit());
posDOF.resize(NVISUALNODE + 1);
rigidDOF->x.endEdit();

rigidDOF->init();
m_omniVisualNode->updateContext();


//creation of subnodes for each part of the device visualization
for(int i=0; i<NVISUALNODE; i++)
for (int i = 0; i<NVISUALNODE; i++)
{
visualNode[i].node = m_omniVisualNode->createChild(visualNodeNames[i]);

if(visualNode[i].visu == NULL && visualNode[i].mapping == NULL)
if (visualNode[i].visu == NULL && visualNode[i].mapping == NULL)
{

// create the visual model and add it to the graph //
Expand All @@ -311,60 +348,38 @@ void GeomagicDriver::init()
visualNode[i].visu->updateVisual();

// create the visual mapping and at it to the graph //
visualNode[i].mapping = sofa::core::objectmodel::New< sofa::component::mapping::RigidMapping< Rigid3dTypes, ExtVec3fTypes > > ();
visualNode[i].mapping = sofa::core::objectmodel::New< sofa::component::mapping::RigidMapping< Rigid3dTypes, ExtVec3fTypes > >();
visualNode[i].node->addObject(visualNode[i].mapping);
visualNode[i].mapping->setModels(rigidDOF.get(), visualNode[i].visu.get());
visualNode[i].mapping->name.setValue("RigidMapping");
visualNode[i].mapping->f_mapConstraints.setValue(false);
visualNode[i].mapping->f_mapForces.setValue(false);
visualNode[i].mapping->f_mapMasses.setValue(false);
visualNode[i].mapping->index.setValue(i+1);
visualNode[i].mapping->index.setValue(i + 1);
visualNode[i].mapping->init();
}
if(i<NVISUALNODE)
if (i<NVISUALNODE)
m_omniVisualNode->removeChild(visualNode[i].node);
}

m_omniVisualNode->updateContext();

for(int i=0; i<NVISUALNODE; i++)
for (int i = 0; i<NVISUALNODE; i++)
{
visualNode[i].node->updateContext();
}

m_initVisuDone = true;

for(int j=0; j<NVISUALNODE; j++)
for (int j = 0; j<NVISUALNODE; j++)
{
sofa::defaulttype::ResizableExtVector< sofa::defaulttype::Vec<3,float> > &scaleMapping = *(visualNode[j].mapping->points.beginEdit());
for(size_t i=0; i<scaleMapping.size(); i++)
sofa::defaulttype::ResizableExtVector< sofa::defaulttype::Vec<3, float> > &scaleMapping = *(visualNode[j].mapping->points.beginEdit());
for (size_t i = 0; i<scaleMapping.size(); i++)
scaleMapping[i] *= (float)(d_scale.getValue());
visualNode[j].mapping->points.endEdit();
}
}

void GeomagicDriver::bwdInit()
{
if(m_errorDevice)
return;

simulation::Node *context = dynamic_cast<simulation::Node *>(this->getContext()); // access to current node
m_forceFeedback = context->get<ForceFeedback>(this->getTags(), sofa::core::objectmodel::BaseContext::SearchRoot);


hdStartScheduler();
HDErrorInfo error;

if (HD_DEVICE_ERROR(error = hdGetError()))
{
msg_info() <<"Failed to start the scheduler";
m_errorDevice = true;
if (m_hStateHandles.size()) m_hStateHandles[0] = HD_INVALID_HANDLE;
return;
}
updatePosition();
}

Mat<4,4, GLdouble> GeomagicDriver::compute_dh_Matrix(double teta,double alpha, double a, double d)
{
Mat<4,4, GLdouble> M;
Expand Down Expand Up @@ -402,7 +417,7 @@ Mat<4,4, GLdouble> GeomagicDriver::compute_dh_Matrix(double teta,double alpha, d

void GeomagicDriver::reinit()
{
if(!m_errorDevice)
if(m_errorDevice != 0)
{
Quat * q_b = d_orientationBase.beginEdit();
q_b->normalize();
Expand All @@ -422,18 +437,15 @@ void GeomagicDriver::updatePosition()
Mat3x3d mrot;

Vector6 & angle = *d_angle.beginEdit();
GeomagicDriver::Coord & posDevice = *d_posDevice.beginEdit();
bool & button_1 = *d_button_1.beginEdit();
bool & button_2 = *d_button_2.beginEdit();
GeomagicDriver::Coord & posDevice = *d_posDevice.beginEdit();

const Vector3 & positionBase = d_positionBase.getValue();
const Quat & orientationBase = d_orientationBase.getValue();
const Quat & orientationTool = d_orientationTool.getValue();
const double & scale = d_scale.getValue();

//copy button state
button_1 = m_simuData.buttonState & HD_DEVICE_BUTTON_1;
button_2 = m_simuData.buttonState & HD_DEVICE_BUTTON_2;
// update button state
updateButtonStates(d_emitButtonEvent.getValue());

//copy angle
angle[0] = m_simuData.angle1[0];
Expand All @@ -460,9 +472,6 @@ void GeomagicDriver::updatePosition()
posDevice.getCenter() = positionBase + orientationBase.rotate(position*scale);
posDevice.getOrientation() = orientationBase * orientation * orientationTool;

d_button_1.endEdit();
d_button_2.endEdit();

if(m_initVisuDone && d_omniVisu.getValue())
{
sofa::defaulttype::SolidTypes<double>::Transform tampon;
Expand Down Expand Up @@ -518,6 +527,53 @@ void GeomagicDriver::updatePosition()
d_angle.endEdit();
}


void GeomagicDriver::updateButtonStates(bool emitEvent)
{
int nbrButton = 2;
sofa::helper::fixed_array<bool, 2> buttons;
buttons[0] = d_button_1.getValue();
buttons[1] = d_button_2.getValue();

//copy button state
sofa::helper::fixed_array<bool, 2> oldStates;
for (int i = 0; i < nbrButton; i++)
oldStates[i] = buttons[i];

// get new values
buttons[0] = m_simuData.buttonState & HD_DEVICE_BUTTON_1;
buttons[1] = m_simuData.buttonState & HD_DEVICE_BUTTON_2;

d_button_1.setValue(buttons[0]);
d_button_2.setValue(buttons[1]);

// emit event if requested
if (!emitEvent)
return;

sofa::simulation::Node::SPtr rootContext = static_cast<simulation::Node*>(this->getContext()->getRootContext());
if (!rootContext)
{
msg_error() << "Rootcontext can't be found using this->getContext()->getRootContext()";
return;
}

for (int i = 0; i < nbrButton; i++)
{
std::string eventString;
if (buttons[i] && !oldStates[i]) // button pressed
eventString = "button" + std::to_string(i) + "pressed";
else if (!buttons[i] && oldStates[i]) // button released
eventString = "button" + std::to_string(i) + "released";

if (!eventString.empty())
{
sofa::core::objectmodel::ScriptEvent eventS(static_cast<simulation::Node*>(this->getContext()), eventString.c_str());
rootContext->propagateEvent(core::ExecParams::defaultInstance(), &eventS);
}
}
}

void GeomagicDriver::getMatrix(Mat<4,4, GLdouble> & M1, int index, double teta)
{
const double ct = cos(teta);
Expand Down Expand Up @@ -548,7 +604,7 @@ void GeomagicDriver::getMatrix(Mat<4,4, GLdouble> & M1, int index, double teta)

void GeomagicDriver::draw(const sofa::core::visual::VisualParams* vparams)
{
if(m_errorDevice)
if(m_errorDevice != 0)
return;

vparams->drawTool()->saveLastState();
Expand Down Expand Up @@ -625,7 +681,7 @@ void GeomagicDriver::draw(const sofa::core::visual::VisualParams* vparams)

void GeomagicDriver::computeBBox(const core::ExecParams* params, bool )
{
if(m_errorDevice)
if(m_errorDevice != 0)
return;

SReal minBBox[3] = {1e10,1e10,1e10};
Expand All @@ -644,7 +700,7 @@ void GeomagicDriver::computeBBox(const core::ExecParams* params, bool )

void GeomagicDriver::handleEvent(core::objectmodel::Event *event)
{
if(m_errorDevice)
if(m_errorDevice != 0)
return;

if (dynamic_cast<sofa::simulation::AnimateBeginEvent *>(event))
Expand Down
Loading