Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/EIPScanner/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ add_subdirectory(utils)
if(ENABLE_VENDOR_SRC)
add_subdirectory(vendor/ra)
add_subdirectory(vendor/yaskawa)
add_subdirectory(vendor/teknic)
endif()


Expand Down
8 changes: 8 additions & 0 deletions src/EIPScanner/vendor/teknic/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
set(SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/clearlink/AttributeBaseObject.cpp
${CMAKE_CURRENT_LIST_DIR}/clearlink/SDMotorConfigObject.cpp
${CMAKE_CURRENT_LIST_DIR}/clearlink/SDMotorInputObject.cpp
${CMAKE_CURRENT_LIST_DIR}/clearlink/SDMotorOutputObject.cpp)

target_sources(EIPScanner PUBLIC ${SOURCE_FILES})
target_sources(EIPScanner PUBLIC ${SOURCE_FILES})
83 changes: 83 additions & 0 deletions src/EIPScanner/vendor/teknic/clearlink/AttributeBaseObject.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
//
// Created by Jan Ritzenhoff on 8/29/2024.
//

#include "EIPScanner/vendor/teknic/clearlink/AttributeBaseObject.h"

#include <memory>

namespace eipScanner
{
namespace vendor
{
namespace teknic
{
namespace clearlink
{
AttributeBaseObject::AttributeBaseObject(eipScanner::cip::CipUint classId, eipScanner::cip::CipUint instanceId,
const eipScanner::SessionInfoIf::SPtr sessionInfo, const eipScanner::MessageRouter::SPtr messageRouter)
: BaseObject(classId, instanceId), _sessionInfo(sessionInfo), _messageRouter(messageRouter) {}

void AttributeBaseObject::_getAllAttributesIndividually()
{
std::vector<ReflexiveFieldReference> classAttributes = _getAttributeReferences();

for (uint8_t fieldIndex = 0; fieldIndex < classAttributes.size(); ++fieldIndex)
{

// actually send the explicit message
auto getAttributeResponse = _messageRouter->sendRequest(_sessionInfo, eipScanner::cip::ServiceCodes::GET_ATTRIBUTE_SINGLE,
eipScanner::cip::EPath(getClassId(), getInstanceId(), fieldIndex + 1));

// check the getAttributeResponse code
if (getAttributeResponse.getGeneralStatusCode() != eipScanner::cip::GeneralStatusCodes::SUCCESS)
{
logGeneralAndAdditionalStatus(getAttributeResponse);
// throw std::runtime_error("Failed to read attribute with status code: " + std::to_string(getAttributeResponse.getGeneralStatusCode()));
continue;
}

eipScanner::utils::Buffer getBuffer(getAttributeResponse.getData());

auto fieldReference = classAttributes[fieldIndex];
// pass a reference of the getBuffer to the lambda function and the first argument of the lambda function is the actual field reference
std::visit([&getBuffer](auto &fieldRef)
{ getBuffer >> fieldRef; },
fieldReference);
}
}

void AttributeBaseObject::_setAllAttributesIndividually()
{
std::vector<ReflexiveFieldReference> classAttributes = _getAttributeReferences();

for (uint8_t fieldIndex = 0; fieldIndex < classAttributes.size(); ++fieldIndex)
{

auto fieldReference = classAttributes[fieldIndex];

eipScanner::utils::Buffer setBuffer;

// pass a reference of the buffer to the lambda function
std::visit([&setBuffer](auto &fieldRef)
{ setBuffer << fieldRef; },
fieldReference);

// actually send the explicit message
auto setAttributeResponse = _messageRouter->sendRequest(_sessionInfo, eipScanner::cip::ServiceCodes::SET_ATTRIBUTE_SINGLE,
eipScanner::cip::EPath(getClassId(), getInstanceId(), fieldIndex + 1),
setBuffer.data());

// check the setAttributeResponse code
if (setAttributeResponse.getGeneralStatusCode() != eipScanner::cip::GeneralStatusCodes::SUCCESS)
{
logGeneralAndAdditionalStatus(setAttributeResponse);
throw std::runtime_error("Failed to read attribute with status code: " + std::to_string(setAttributeResponse.getGeneralStatusCode()));
}
}
}

}
}
}
}
82 changes: 82 additions & 0 deletions src/EIPScanner/vendor/teknic/clearlink/AttributeBaseObject.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
//
// Created by Jan Ritzenhoff on 8/29/2024.
//

#ifndef EIPSCANNER_VENDOR_TEKNIC_CLEARLINK_ATTRIBUTEBASEOBJECT_H
#define EIPSCANNER_VENDOR_TEKNIC_CLEARLINK_ATTRIBUTEBASEOBJECT_H

#include <variant>
#include <functional>
#include <vector>

#include "EIPScanner/cip/Types.h"
#include "EIPScanner/BaseObject.h"
#include "EIPScanner/SessionInfo.h"
#include "EIPScanner/MessageRouter.h"

#include "EIPScanner/utils/Buffer.h"

namespace eipScanner
{
namespace vendor
{
namespace teknic
{
namespace clearlink
{

/**
* @class AttributeBaseObject
*
* @brief Base class for all the CIP Objects that access all attributes independently using explicit messaging
*/
class AttributeBaseObject : public eipScanner::BaseObject
{
public:
/**
* @brief Creates an CIP instance
* @param classId the class ID of the the new instance
* @param instanceId the instance ID of the the new instanc
*/
AttributeBaseObject(eipScanner::cip::CipUint classId, eipScanner::cip::CipUint instanceId, const eipScanner::SessionInfoIf::SPtr sessionInfo, const eipScanner::MessageRouter::SPtr messageRouter);

protected:
using ReflexiveFieldReference = std::variant<std::reference_wrapper<eipScanner::cip::CipOctet>,
std::reference_wrapper<eipScanner::cip::CipBool>,
std::reference_wrapper<eipScanner::cip::CipByte>,
std::reference_wrapper<eipScanner::cip::CipWord>,
std::reference_wrapper<eipScanner::cip::CipDword>,
std::reference_wrapper<eipScanner::cip::CipUsint>,
std::reference_wrapper<eipScanner::cip::CipUint>,
std::reference_wrapper<eipScanner::cip::CipSint>,
std::reference_wrapper<eipScanner::cip::CipInt>,
std::reference_wrapper<eipScanner::cip::CipDint>,
std::reference_wrapper<eipScanner::cip::CipReal>,
std::reference_wrapper<eipScanner::cip::CipLreal>,
std::reference_wrapper<eipScanner::cip::CipLword>,
std::reference_wrapper<eipScanner::cip::CipLint>,
std::reference_wrapper<eipScanner::cip::CipUlint>>;
// std::reference_wrapper<eipScanner::cip::CipUdint>, (this is typedeffed' to the same thing as the DWord. Including both in the variant confuses the compiler)

virtual std::vector<ReflexiveFieldReference> _getAttributeReferences() = 0;

/**
* @brief Gets the whole assembly to the device as individual get_attribute_single messages
*/
void _getAllAttributesIndividually();

/**
* @brief Sets the whole assembly to the device as individual set_attribute_single messages
*/
void _setAllAttributesIndividually();

private:
const eipScanner::SessionInfoIf::SPtr _sessionInfo;
const eipScanner::MessageRouter::SPtr _messageRouter;
};
}
}
}
}

#endif // EIPSCANNER_VENDOR_TEKNIC_CLEARLINK_ATTRIBUTEBASEOBJECT_H
81 changes: 81 additions & 0 deletions src/EIPScanner/vendor/teknic/clearlink/SDMotorConfigObject.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//
// Created by Jan Ritzenhoff on 8/28/2024
//
#include "EIPScanner/vendor/teknic/clearlink/SDMotorConfigObject.h"

#include "EIPScanner/utils/Buffer.h"

#include <type_traits>

namespace eipScanner
{
namespace vendor
{
namespace teknic
{
namespace clearlink
{
using eipScanner::utils::Buffer;

SDMotorConfigObject::SDMotorConfigObject(eipScanner::cip::CipUint instanceId, const eipScanner::SessionInfoIf::SPtr si, const eipScanner::MessageRouter::SPtr messageRouter)
: AttributeBaseObject(CLASS_ID, instanceId, si, messageRouter), _configRegister(0), _softLimitPosition1(0), _softLimitPosition2(0), _positiveLimitConnector(0), _negativeLimitConnector(0), _homeSensorConnector(0), _brakeOutputConnector(0), _triggerPositionCaptureConnector(0), _maxDecelerationRate(0), _stopSensorConnector(0), _followEncoderMode(0), _followDivisor(0), _followMultiplier(0)
{

_getAllAttributesIndividually();
}

void SDMotorConfigObject::setAllAttributesIndividually()
{
_setAllAttributesIndividually();
}

std::vector<AttributeBaseObject::ReflexiveFieldReference> SDMotorConfigObject::_getAttributeReferences()
{
return {std::ref(_configRegister), std::ref(_softLimitPosition1), std::ref(_softLimitPosition2),
std::ref(_positiveLimitConnector), std::ref(_negativeLimitConnector), std::ref(_homeSensorConnector),
std::ref(_brakeOutputConnector), std::ref(_triggerPositionCaptureConnector), std::ref(_maxDecelerationRate),
std::ref(_stopSensorConnector), std::ref(_followEncoderMode), std::ref(_followDivisor), std::ref(_followMultiplier)};
}

eipScanner::cip::CipDword SDMotorConfigObject::getConfigRegister() const { return _configRegister; }
void SDMotorConfigObject::setConfigRegister(eipScanner::cip::CipDword configRegister) { _configRegister = configRegister; }

eipScanner::cip::CipDint SDMotorConfigObject::getSoftLimitPosition1() const { return _softLimitPosition1; }
void SDMotorConfigObject::setSoftLimitPosition1(eipScanner::cip::CipDint softLimitPosition1) { _softLimitPosition1 = softLimitPosition1; }

eipScanner::cip::CipDint SDMotorConfigObject::getSoftLimitPosition2() const { return _softLimitPosition2; }
void SDMotorConfigObject::setSoftLimitPosition2(eipScanner::cip::CipDint softLimitPosition2) { _softLimitPosition2 = softLimitPosition2; }

eipScanner::cip::CipSint SDMotorConfigObject::getPositiveLimitConnector() const { return _positiveLimitConnector; }
void SDMotorConfigObject::setPositiveLimitConnector(eipScanner::cip::CipSint positiveLimitConnector) { _positiveLimitConnector = positiveLimitConnector; }

eipScanner::cip::CipSint SDMotorConfigObject::getNegativeLimitConnector() const { return _negativeLimitConnector; }
void SDMotorConfigObject::setNegativeLimitConnector(eipScanner::cip::CipSint negativeLimitConnector) { _negativeLimitConnector = negativeLimitConnector; }

eipScanner::cip::CipSint SDMotorConfigObject::getHomeSensorConnector() const { return _homeSensorConnector; }
void SDMotorConfigObject::setHomeSensorConnector(eipScanner::cip::CipSint homeSensorConnector) { _homeSensorConnector = homeSensorConnector; }

eipScanner::cip::CipSint SDMotorConfigObject::getBrakeOutputConnector() const { return _brakeOutputConnector; }
void SDMotorConfigObject::setBrakeOutputConnector(eipScanner::cip::CipSint brakeOutputConnector) { _brakeOutputConnector = brakeOutputConnector; }

eipScanner::cip::CipSint SDMotorConfigObject::getTriggerPositionCaptureConnector() const { return _triggerPositionCaptureConnector; }
void SDMotorConfigObject::setTriggerPositionCaptureConnector(eipScanner::cip::CipSint triggerPositionCaptureConnector) { _triggerPositionCaptureConnector = triggerPositionCaptureConnector; }

eipScanner::cip::CipDint SDMotorConfigObject::getMaxDecelerationRate() const { return _maxDecelerationRate; }
void SDMotorConfigObject::setMaxDecelerationRate(eipScanner::cip::CipDint maxDecelerationRate) { _maxDecelerationRate = maxDecelerationRate; }

eipScanner::cip::CipSint SDMotorConfigObject::getStopSensorConnector() const { return _stopSensorConnector; }
void SDMotorConfigObject::setStopSensorConnector(eipScanner::cip::CipSint stopSensorConnector) { _stopSensorConnector = stopSensorConnector; }

eipScanner::cip::CipSint SDMotorConfigObject::getFollowEncoderMode() const { return _followEncoderMode; }
void SDMotorConfigObject::setFollowEncoderMode(eipScanner::cip::CipSint followEncoderMode) { _followEncoderMode = followEncoderMode; }

eipScanner::cip::CipDint SDMotorConfigObject::getFollowDivisor() const { return _followDivisor; }
void SDMotorConfigObject::setFollowDivisor(eipScanner::cip::CipDint followDivisor) { _followDivisor = followDivisor; }

eipScanner::cip::CipDint SDMotorConfigObject::getFollowMultiplier() const { return _followMultiplier; }
void SDMotorConfigObject::setFollowMultiplier(eipScanner::cip::CipDint followMultiplier) { _followMultiplier = followMultiplier; }
}
}
}
}
Loading