...
 
......@@ -34,7 +34,7 @@
######################################################
###################USER###############################
PROJECT_NAME =emros
MODULES =NanoOFC/core NanoOFC/logger utility_ofc devices system motors basecontroller emros_common gui helper
MODULES =NanoOFC/core NanoOFC/logger utility_ofc devices system motors basecontroller robotstatecontroller emros_common gui helper
OUTPUT_NAME =debuggee.emp
USER_LIBS =
......
Subproject commit 943d700fb3d68c51ad3fc584ca323199498d3abb
Subproject commit 10bc6fcde66fbc1cf70ddf30dc479b6b55028a62
......@@ -13,19 +13,20 @@
#include "../../../nanotec/inc/nanoj.h"
#include <cmath>
#include "../../utility_ofc/include/utility_ofc/leaky_bucket_timeout.h"
#include "../../motors/inc/can_helper.h"
#include "../../NanoOFC/core/inc/nano_ofc.h"
#include <cstring>
#include "../../motors/inc/can_helper.h"
#include "../../utility_ofc/include/utility_ofc/ethprotocol.h"
#include "ramp_generator.h"
#include "../../system/inc/factories.h"
#include "basecontroller_types.h"
#ifdef DEF_4WD
#include "../../motors/inc/can_mapping_4WD.h"
#include "../../motors/inc/pdo_mapping_4WD.h"
#elif defined DEF_2WD
#include "../../motors/inc/can_mapping_2WD.h"
#include "../../motors/inc/pdo_mapping_2WD.h"
#elif defined DEF_2WD_PLUS_AUX
#include "../../motors/inc/can_mapping_2WD_plus_auxiliary.h"
#include "../../motors/inc/pdo_mapping_2WD_plus_auxiliary.h"
#endif
#include <vector>
#include "../../system/inc/msg.h"
......@@ -37,36 +38,29 @@ class Basecontroller
public:
struct Status
{
static const uint8_t Operational_enabled = 0x01;
static const uint8_t Fault = 0x02;
static const uint8_t Sync = 0x04;
static const uint8_t Quick_stop = 0x08;
};
// struct Status
// {
// static const uint8_t Operational_enabled = 0x01;
// static const uint8_t Fault = 0x02;
// static const uint8_t Sync = 0x04;
// static const uint8_t Quick_stop = 0x08;
// };
Basecontroller();
~Basecontroller();
Error CyclicProcess();
Error CheckButton(os_msg_t& msg);
// void GetCSVMode(bool * mode)
// {
// *mode = mCSV_mode_enabled;
// } //TODO: this is provisional because of current development state of EM5
//should not used anymore in later versions
Error CheckButton(os_msg_t& msg);
private:
Error MsgBoxCallback(const MsgBoxHandler::Dataframe& dataframe);
Error MsgBoxCallbackBroadcast(const MsgBoxHandler::Dataframe& dataframe);
Error EthMsgCallback(const EthHandler::Dataframe& dataframe);
Error DelayedCANSyncCallback();
Error FilterAndSendActualVelocitiesCallback();
Error CyclicCANSyncCallback();
Error CyclicTimerCallback();
void UpdateVelocities();
......@@ -82,7 +76,6 @@ private:
bool mCSV_mode_enabled;
bool mHearbeat;
bool mCritical_fault;
uint32_t mSyncTimeDelay;
......@@ -93,7 +86,7 @@ private:
int8_t* mCAN_modes_of_operation_display; // 6061
//---------------------------------------------
std::vector<Motor*>* mMotors;
std::vector<MotorPdoMapping*>* mMotors;
TargetVelocitiesInterface* mTargetVelocities;
TargetVelocitiesInterface* mRampedVelocities;
ActualVelocitiesInterface* mActualVelocities;
......
......@@ -22,8 +22,8 @@ template<typename VEL_T>
struct RampConfig
{
uint32_t dt;
uint32_t max_acceleration;
uint32_t interval_in_us;
uint32_t max_acceleration_in_rad_per_sec_squared;
};
......@@ -61,8 +61,8 @@ template<typename VEL_T>
Error RampGenerator<VEL_T>::Init(RampConfig config)
{
std::memcpy(&mConfig, &config, sizeof(RampConfig));
mRamp_step = uint32_t(mConfig.max_acceleration * (mConfig.dt / 1000.0)); //U/min
mDt_conv_s = float(mConfig.dt) / 1000.0f;
mRamp_step = uint32_t(mConfig.max_acceleration_in_rad_per_sec_squared * (mConfig.interval_in_us / 1.0E6)); //U/min
mDt_conv_s = float(mConfig.interval_in_us) / 1.0E6f;
mLast_velocities = InstanceFactory::instance()->GetTargetVelocitiesInstance();
if(!&mLast_velocities)
{
......@@ -101,34 +101,34 @@ template<typename VEL_T>
float target_acc { float(target_velocities.dataByType()[index] - mLast_velocities->dataByType()[index]) / float(mDt_conv_s)};
VEL_T new_velocity = target_velocities.dataByType()[index];
if (target_velocities.dataByType()[index] > 0 && target_acc > 0 && std::abs(target_acc) > mConfig.max_acceleration)
if (target_velocities.dataByType()[index] > 0 && target_acc > 0 && std::abs(target_acc) > mConfig.max_acceleration_in_rad_per_sec_squared)
{ //acceleration ramp positive direction
new_velocity = mRamp_step + mLast_velocities->dataByType()[index];
}
else if (target_velocities.dataByType()[index] > 0 && target_acc < 0
&& std::abs(target_acc) > mConfig.max_acceleration)
&& std::abs(target_acc) > mConfig.max_acceleration_in_rad_per_sec_squared)
{ //deceleration ramp positive direction
new_velocity = -mRamp_step + mLast_velocities->dataByType()[index];
}
else if (target_velocities.dataByType()[index] < 0 && target_acc < 0
&& std::abs(target_acc) > mConfig.max_acceleration)
&& std::abs(target_acc) > mConfig.max_acceleration_in_rad_per_sec_squared)
{ //acceleration ramp negative direction
new_velocity = -mRamp_step + mLast_velocities->dataByType()[index];
}
else if (target_velocities.dataByType()[index] < 0 && target_acc > 0
&& std::abs(target_acc) > mConfig.max_acceleration)
&& std::abs(target_acc) > mConfig.max_acceleration_in_rad_per_sec_squared)
{ //deceleration ramp negative direction
new_velocity = mRamp_step + mLast_velocities->dataByType()[index];
}
else if (target_velocities.dataByType()[index] == 0 && target_acc < 0
&& std::abs(target_acc) > mConfig.max_acceleration)
&& std::abs(target_acc) > mConfig.max_acceleration_in_rad_per_sec_squared)
{ //deceleration ramp positive direction
new_velocity = -mRamp_step + mLast_velocities->dataByType()[index];
}
else if (target_velocities.dataByType()[index] == 0 && target_acc > 0
&& std::abs(target_acc) > mConfig.max_acceleration)
&& std::abs(target_acc) > mConfig.max_acceleration_in_rad_per_sec_squared)
{ //deceleration ramp negative direction
new_velocity = mRamp_step + mLast_velocities->dataByType()[index];
}
......
......@@ -8,6 +8,14 @@
#include "../inc/basecontroller.h"
namespace{
const int every_cansync_event = 1;
const TimerHandler::timer_event_t every_timer_event = 1;
const uint32_t filter_period_in_cansyncs = 8;
}
Basecontroller::Basecontroller() :
mInstanceFactory(*InstanceFactory::instance()),
mCanHelper(*CanHelper::instance()),
......@@ -16,33 +24,30 @@ Basecontroller::Basecontroller() :
mCSV_mode_enabled(false),
mHearbeat(true),
mCritical_fault(false),
mSyncTimeDelay(8),
mStatus_word(mInstanceFactory.GetMotorStatusInstance()),
mCAN_modes_of_operation_display(),
mMotors(mInstanceFactory.GetMotors()),
mTargetVelocities(mInstanceFactory.GetTargetVelocitiesInstance()),
mActualVelocities(mInstanceFactory.GetActualVelocitiesInstance()),
mBase_config(),
mRampedVelocities(mInstanceFactory.GetTargetVelocitiesInstance()),
mAverageVelocities(mInstanceFactory.GetActualVelocitiesInstance()),
mObserver_eth(mDevice_id,&Basecontroller::EthMsgCallback,this),
mObserver_msg_box(mDevice_id,&Basecontroller::MsgBoxCallback,this),
mObserver_msg_box_broadcast(EMROSCmdType::BROADCAST_ID,&Basecontroller::MsgBoxCallbackBroadcast,this),
mObserver_cyclic_can_sync(1,&Basecontroller::CyclicCANSyncCallback,this),
mObserver_delayed_can_sync(mSyncTimeDelay,&Basecontroller::DelayedCANSyncCallback,this)
mObserver_cyclic_can_sync(every_cansync_event,&Basecontroller::CyclicCANSyncCallback,this),
mObserver_delayed_can_sync(filter_period_in_cansyncs,&Basecontroller::FilterAndSendActualVelocitiesCallback,this)
{
mCAN_modes_of_operation_display = new int8_t[mMotors->size()];
if (!(mTargetVelocities && mActualVelocities && mRampedVelocities && mStatus_word))
{
//TODO: error
OFCLoggerRTClient::instance()->InsertCriticalError(__PRETTY_FUNCTION__,"resource init failed");
OFCLoggerRTClient::instance()->InsertCriticalError(__PRETTY_FUNCTION__,"resource init failed");
}
mBase_config.dt = mSyncTimeDelay;
mBase_config.max_acceleration = 30000;
mBase_config.interval_in_us = CANSyncHandler::instance()->GetCanSyncIntervalInUs();
mBase_config.max_acceleration_in_rad_per_sec_squared = 30000;
mRamp.Init(mBase_config);
}
......@@ -60,36 +65,13 @@ Basecontroller::~Basecontroller()
}
Error Basecontroller::CheckButton(os_msg_t& msg)
{
if (System::IsUserMsg(msg,BUTTON_ENABLE_MOTORS))
{
OFCLoggerRTClient::instance()->InsertDebug("Button Enable Motors");
if(mCSV_mode_enabled == true)
{
mCanHelper.AppDisableCsvMode();
mCSV_mode_enabled = !mCSV_mode_enabled;
}
else
{
mCanHelper.AppEnableCsvMode();
mCSV_mode_enabled = !mCSV_mode_enabled;
}
}
return (Error::NO_ERROR);
}
Error Basecontroller::CyclicProcess(void)
{
mCanHelper.AppProcessCsvMode();
return (Error::NO_ERROR);
}
//Error Basecontroller::CyclicTimerCallback(void)
//{
// mCanHelper.AppProcessCsvMode();
// return (Error::NO_ERROR);
//}
......@@ -147,15 +129,15 @@ Error Basecontroller::MsgBoxCallback(const MsgBoxHandler::Dataframe& dataframe)
break;
case ENABLE_CSV_MODE:
mCSV_mode_enabled = true;
break;
case DISABLE_CSV_MODE:
mCSV_mode_enabled = false;
break;
// case ENABLE_CSV_MODE:
//
// mCSV_mode_enabled = true;
// break;
//
// case DISABLE_CSV_MODE:
//
// mCSV_mode_enabled = false;
// break;
case EMROSCmdType::Security::CMD_VEL_DOWNLINK_TIMEOUT:
//set target velocities to zero
......@@ -171,15 +153,14 @@ Error Basecontroller::MsgBoxCallback(const MsgBoxHandler::Dataframe& dataframe)
{
switch (dataframe.getData().cmd)
{
case EMROSCmdType::Service::ENABLE_SYNC:
case EMROSCmdType::Service::ENABLE_SYNC: //TODO: Move to Robot-State-Controller
mRos_link_enabled = true;
break;
case EMROSCmdType::Service::DISABLE_SYNC:
case EMROSCmdType::Service::DISABLE_SYNC: //TODO: Move to Robot-State-Controller
mRos_link_enabled =false;
mTargetVelocities->clearData();
break;
case EMROSCmdType::Security::HEARTBEAT:
case EMROSCmdType::Security::HEARTBEAT: //TODO: Move to Robot-State-Controller
mHearbeat = true;
break;
......@@ -210,7 +191,7 @@ Error Basecontroller::MsgBoxCallback(const MsgBoxHandler::Dataframe& dataframe)
}
break;
case ENABLE_CSV_MODE:
case ENABLE_CSV_MODE: //TODO: Move to Robot-State-Controller
mCSV_mode_enabled = true;
tx_eth_msg.setData().id = mDevice_id;
tx_eth_msg.setData().cmd = ENABLE_CSV_MODE;
......@@ -222,7 +203,7 @@ Error Basecontroller::MsgBoxCallback(const MsgBoxHandler::Dataframe& dataframe)
}
break;
case DISABLE_CSV_MODE:
case DISABLE_CSV_MODE: //TODO: Move to Robot-State-Controller
mCSV_mode_enabled = false;
tx_eth_msg.setData().id = mDevice_id;
tx_eth_msg.setData().cmd = DISABLE_CSV_MODE;
......@@ -265,7 +246,7 @@ Error Basecontroller::CyclicCANSyncCallback()
motor->getModeOfOperationDisplay(mCAN_modes_of_operation_display[i]);
i++;
}
//TODO: Move to Robot-State-Controller -- START
if (mHearbeat == true)
{
mHearbeat = false;
......@@ -280,6 +261,8 @@ Error Basecontroller::CyclicCANSyncCallback()
OFCLoggerRTClient::instance()->InsertCriticalError(__PRETTY_FUNCTION__, "security hearbeat failed");
return (Error::ERROR);
}
//TODO: Move to Robot-State-Controller -- END
if (mRos_link_enabled == true)
{
mAverageVelocities->addVelocities(mActualVelocities->dataByType(), mActualVelocities->getNumberOfMotors());
......@@ -288,7 +271,7 @@ Error Basecontroller::CyclicCANSyncCallback()
return (Error::NO_ERROR);
}
Error Basecontroller::DelayedCANSyncCallback()
Error Basecontroller::FilterAndSendActualVelocitiesCallback()
{
Error status {Error::NO_ERROR};
......@@ -296,11 +279,11 @@ Error Basecontroller::DelayedCANSyncCallback()
{
EthHandler::Dataframe tx_eth_msg;
mAverageVelocities->calcAverage(uint8_t(mSyncTimeDelay));
mAverageVelocities->calcAverage(uint8_t(filter_period_in_cansyncs));
tx_eth_msg.setData().id = mDevice_id;
tx_eth_msg.setData().cmd = ACTUAL_VELOCITIES;
tx_eth_msg.setData().time = CANSyncHandler::instance()->GetCurrentSyncTime();
tx_eth_msg.setData().time = CANSyncHandler::instance()->GetTimeOfLastSyncInUs();
status = mAverageVelocities->get(tx_eth_msg.setData().payload.begin(), Ethprotocol::MAX_PAYLOAD_LENGTH);
if (status != Error::NO_ERROR)
{
......
/*
* service_bridge.h
*
* Created on: Apr 5, 2017
* Author: speckle_s
*/
#ifndef EMROS_EMROS_INC_SERVICE_BRIDGE_H_
#define EMROS_EMROS_INC_SERVICE_BRIDGE_H_
//#include "nanoj.h"
//#include "../../core/inc/nano_ofc.h"
//#include "emros_commands.h"
//#include "datacontainer.h"
//#include <stdint.h>
//#include <cstring>
//
//
//
//class ServiceBridge
//{
//private:
// enum class States
// {
// IDLE, SDO_DOWNLOAD, SDO_UPLOAD, ERROR
// };
// enum class Datatypes
// {
// STRING = 0, UNSIGNED8 = 1, UNSIGNED16 = 2, UNSIGNED32 = 3, SIGNED8 = 4, SIGNED16 = 5, SIGNED32 = 6
// };
// enum class Accesscodes
// {
// WRITE = 0, READ = 1
// };
//
//public:
// struct Data
// {
// uint32_t seq;
// uint32_t node_id;
// uint32_t datatype;
// uint32_t objectcode;
// uint32_t access;
// uint32_t index;
// uint32_t subindex;
// uint32_t value;
// };
// typedef Container<Data> DataContainer;
//
// ServiceBridge() :
// mStates(States::IDLE), mData()
// {
// }
//
// ~ServiceBridge()
// {
// }
//
// //Error NewSdoEvent(os_msg_t msg);
//
//private:
//
//
//
// EthHandler::ObserverEthHandler mObserver_eth;
// MsgBoxHandler::ObserverMsgBox mObserver_msg_box;
// MsgBoxHandler::ObserverMsgBox mObserver_msg_box_broadcast;
//
//
//
//
// EthHandler::DeviceId mDevice_id;
// bool mROS_link_enabled;
// size_t DatatypesToDatalength(uint32_t type);
// States mStates;
// DataContainer mData;
// Ethprotocol mEthProtocol;
//
//};
#endif /* EMROS_EMROS_INC_SERVICE_BRIDGE_H_ */
......@@ -55,7 +55,7 @@ Error SdoBridge::ethCallback(const EthHandler::Dataframe& data)
//TODO: check for len=0 ?
if (data.getData().cmd == EMROSCmdType::ServiceBridge::SDO_RX) //~JG READ_SDO
if (data.getData().cmd == EMROSCmdType::SdoBridge::SDO_RX) //~JG READ_SDO
{
SdoHandler::SdoUploadData upload_data {};
upload_data.node_id = mSdo_request.node_id; //~JG
......@@ -71,7 +71,7 @@ Error SdoBridge::ethCallback(const EthHandler::Dataframe& data)
mSdo_request_pending = true;
mSdo_request_timeout.resetTime();
}
else if (data.getData().cmd == EMROSCmdType::ServiceBridge::SDO_TX) // ~JG WRITE_SDO
else if (data.getData().cmd == EMROSCmdType::SdoBridge::SDO_TX) // ~JG WRITE_SDO
{
SdoHandler::SdoDownloadData download_data {};
download_data.node_id = mSdo_request.node_id; //~JG
......
/*
* service_bridge.cpp
*
* Created on: Apr 5, 2017
* Author: speckle_s
*/
#include "../inc/service_bridge.h"
//Error ServiceBridge::new_sdo_event(os_msg_t msg)
//{
// uint32_t transmittedBytes;
// uint32_t abortCode;
// tCmState extendedStatus;
//
// EMROSInterface::Config_t config;
// EMROSInterface::getConfig(&config);
//
// uint32_t sync_time;
// getCurrentSyncTime(&sync_time);
//
// Error::eError status = Error::NoError;
// switch (mStates)
//
// {
// case States::IDLE:
// ;
// break;
//
// case States::SDO_DOWNLOAD:
// Can::GetSdoData(msg.tag, &extendedStatus, &abortCode, &transmittedBytes, NULL, 0);
// if (abortCode == 0)
// {
// ethprotocol_types::Dataframe rx_eth_data;
// rx_eth_data.data().ID = config.ID;
// rx_eth_data.data().Cmd = service_bridge::SDO_RX;
// rx_eth_data.data().Payload_length = mData.MAX_DATA_LENGTH;
// rx_eth_data.data().Time = System::GetReferenceTimer();
// mData.get(rx_eth_data.data().Payload, ethprotocol_types::MAX_PAYLOAD_LENGTH);
// EMROSInterface::sendEthMsg(&rx_eth_data);
// mStates = States::IDLE;
// }
// else
// {
// char str[100] = {};
// sprintf(str, "SDO Download error errorcode: %lu extendedStatus: %u", abortCode, extendedStatus);
// EMROSInterface::logMsg(str);
// mStates = States::IDLE;
// }
// break;
//
// case States::SDO_UPLOAD:
// Can::GetSdoData(msg.tag, &extendedStatus, &abortCode, &transmittedBytes, &mData.data().value,
// sizeof(mData.data().value));
// if (abortCode == 0)
// {
// ethprotocol_types::Dataframe rx_eth_data;
// rx_eth_data.data().ID = config.ID;
// rx_eth_data.data().Cmd = service_bridge::SDO_RX;
// rx_eth_data.data().Payload_length = mData.MAX_DATA_LENGTH;
// rx_eth_data.data().Time = System::GetReferenceTimer();
// mData.get(rx_eth_data.data().Payload, ethprotocol_types::MAX_PAYLOAD_LENGTH);
// EMROSInterface::sendEthMsg(&rx_eth_data);
// mStates = States::IDLE;
// }
// else
// {
// char str[100] = {};
// sprintf(str, "SDO Upload error errorcode: %lu extendedStatus: %u", abortCode, extendedStatus);
// EMROSInterface::logMsg(str);
// mStates = States::IDLE;
// }
// break;
//
// case States::ERROR:
// //TODO: Error;
//
// break;
//
// }
// //Send Data in Tx buffer
// //TODO: Interface for Ethernet sending --> Ethernetprotocol or MSGHandler --> polymorph
//
// ethprotocol_types::Buffer* buffer;
// mEthProtocol.getEthBuffer(buffer);
// if (buffer->length != 0)
// {
// size_t size = Network::WriteData(buffer->data, buffer->length);
// if (size != buffer->length)
// {
// status = Error::MsgHandler_newMsg_sendError;
// }
// mEthProtocol.clearEthBuffer();
// }
// return status;
//}
//
//size_t ServiceBridge::DatatypesToDatalength(uint32_t type)
//
//{
// if (type == Datatypes::STRING || type == Datatypes::SIGNED8 || type == Datatypes::UNSIGNED8)
// {
// return 1;
// }
// else if (type == Datatypes::SIGNED16 || type == Datatypes::UNSIGNED16)
// {
// return 2;
// }
// else if (type == Datatypes::SIGNED32 || type == Datatypes::UNSIGNED32)
// {
// return 4;
// }
// else
// {
// return 4;
// }
//
//}
//
//Error ServiceBridge::ethMsgUpdate(ethprotocol_types::id_t ID)
//{
// EMROSInterface::Config_t config;
// EMROSInterface::getConfig(&config);
// bool sync_status;
// EMROSInterface::getSyncStatus(&sync_status);
// if (config.ID == ID && sync_status)
// {
// ethprotocol_types::Dataframe rx_eth_data;
// EMROSInterface::getEthMsg(&rx_eth_data);
// if (rx_eth_data.data().Cmd == service_bridge::SDO_TX && mStates == States::IDLE)
// {
// mData.set(rx_eth_data.data().Payload, rx_eth_data.data().Payload_length);
// if (mData.data().access == Accesscodes::WRITE)
// {
// Can::SdoDownload(1, mData.data().index, mData.data().subindex, &mData.data().value,
// DatatypesToDatalength(mData.data().datatype));
// mStates = States::SDO_DOWNLOAD;
//// char str[50] = {};
//// sprintf(str,"SDO download index: %lx subindex %lx value: %lu", mData.data().index, mData.data().subindex,mData.data().value);
//// EMROSInterface::logMsg(str);
// }
// else if (mData.data().access == Accesscodes::READ)
// {
// Can::SdoUpload(1, mData.data().index, mData.data().subindex);
//// char str[50] = {};
//// sprintf(str,"SDO upload index: %lx subindex %lx", mData.data().index, mData.data().subindex);
//// EMROSInterface::logMsg(str);
// mStates = States::SDO_UPLOAD;
// }
// }
// else
// {
// //TODO: return Error
// }
// }
// return Error::NoError;
//}
//
//Error::eError ServiceBridge::msgBoxUpdate(ethprotocol_types::id_t ID)
//{
// EMROSInterface::Config_t config;
// EMROSInterface::getConfig(&config);
//
// Error::eError status = Error::NoError;
//
// if (ID == BROADCAST_ID)
// {
// EMROS::MsgBox::Data msg;
// getMsgBoxMsg(&msg);
// switch (msg.data().Cmd)
// {
// case service::ENABLE_SYNC:
// setSyncStatus(true);
// break;
// case service::DISABLE_SYNC:
// setSyncStatus(false);
// break;
//
// default:
// break;
// }
// }
// return status;
//}
Subproject commit d0b36c0c119f6fc49f746d0ca65fc58bd378f5e0
Subproject commit 0325cd0a0ca961f9228f99de8050dfea98ec1f65
......@@ -122,8 +122,10 @@ class MecanumGUI final : public Interface
{
public:
MecanumGUI():
mMotor_front_left(*MotorManagerWD::instance()->getMotor("MotorFrontLeft")),mMotor_front_right(*MotorManagerWD::instance()->getMotor("MotorFrontRight")),
mMotor_rear_left(*MotorManagerWD::instance()->getMotor("MotorRearLeft")),mMotor_rear_right(*MotorManagerWD::instance()->getMotor("MotorRearRight"))
mMotor_front_left(*MotorManagerWD::instance()->getMotor("MotorFrontLeft")),
mMotor_front_right(*MotorManagerWD::instance()->getMotor("MotorFrontRight")),
mMotor_rear_left(*MotorManagerWD::instance()->getMotor("MotorRearLeft")),
mMotor_rear_right(*MotorManagerWD::instance()->getMotor("MotorRearRight"))
{
Graphics::SelectLayer(LAYER_TOP);
Graphics::ClearScreen(COLOR_BLACK);
......
......@@ -212,10 +212,10 @@ Error MecanumGUI::HandleRTOutput()
int32_t actual_wheel_fr, actual_wheel_fl, actual_wheel_rr, actual_wheel_rl;
char string[500]{0};
mMotor_front_left.getVelocityActualValue(actual_wheel_fl);
mMotor_front_right.getVelocityActualValue(actual_wheel_fr);
mMotor_rear_left.getVelocityActualValue(actual_wheel_rl);
mMotor_rear_right.getVelocityActualValue(actual_wheel_rr);
mMotor_front_left.getPdoHandle()->getVelocityActualValue(actual_wheel_fl);
mMotor_front_right.getPdoHandle()->getVelocityActualValue(actual_wheel_fr);
mMotor_rear_left.getPdoHandle()->getVelocityActualValue(actual_wheel_rl);
mMotor_rear_right.getPdoHandle()->getVelocityActualValue(actual_wheel_rr);
std::snprintf(string,500, "Actual vel: \nFL: %li \nFR: %li \nRL: %li \nRR: %li\n", actual_wheel_fl, actual_wheel_fr, actual_wheel_rl, actual_wheel_rr);
Graphics::SelectColor(COLOR_BLUE);
......@@ -444,10 +444,10 @@ Error DifferentialGUI::HandleRTOutput()
char string[500] {0};
mMotor_left.getVelocityActualValue(actual_vel_wheel_left);
mMotor_right.getVelocityActualValue(actual_vel_wheel_right);
mMotor_left.getTargetVelocity(target_vel_wheel_left);
mMotor_right.getTargetVelocity(target_vel_wheel_right);
mMotor_left.getPdoHandle()->getVelocityActualValue(actual_vel_wheel_left);
mMotor_right.getPdoHandle()->getVelocityActualValue(actual_vel_wheel_right);
mMotor_left.getPdoHandle()->getTargetVelocity(target_vel_wheel_left);
mMotor_right.getPdoHandle()->getTargetVelocity(target_vel_wheel_right);
std::snprintf(string, 500, "Actual \nvelocities: \nL: %li \nR: %li \nTarget \nvelocities: \nL: %li \nR: %li \nBattery \nV: %limV \nA: %limA \nCap: %imAh",
actual_vel_wheel_left, actual_vel_wheel_right, target_vel_wheel_left, target_vel_wheel_right, batteryVoltage_mV, batteryCurrent_mA, batteryRemCap_mAh);
......
......@@ -16,10 +16,10 @@
#include "NanoOFC/logger/inc/ofc_client_RT.h"
#include "system/inc/msg.h"
#include "basecontroller/inc/basecontroller.h"
#include "robotstatecontroller/inc/robotstatecontroller.h"
#include "devices/inc/service.h"
#include "devices/inc/security.h"
#include "gui/inc/emros_gui.h"
#include "utility_ofc/include/utility_ofc/timeout.h"
#include "utility_ofc/include/utility_ofc/map_extractor.h"
#include "emros_common/include/emros_common/wheel_drive_config.h"
#include "helper/inc/bringup_helper.h"
......@@ -28,7 +28,7 @@
namespace {
const char ip_ros_pc[] ="192.168.60.55"; // <-- PLEASE SET THE IP OF YOUR MACHINE HERE!
const uint16_t can_sync_time_us = 8000;
const uint16_t can_sync_interval_us = 8000;
const uint16_t port_ros_pc = 65000;
const uint32_t timeout_can_bootup_us = 1E6;
const uint32_t timeout_rt_task_mainloop_ms = 10;
......@@ -94,43 +94,44 @@ void RealtimeTask(void) {
#endif
SdoHandler::instance()->Init();
CANSyncHandler::instance()->Init();
CANSyncHandler::instance()->Init(can_sync_interval_us);
Security security { };
Basecontroller basecontroller = Basecontroller();
Robotstatecontroller robotstatecontroller { };
Service service { };
CanHelper::instance()->init();
myLogger.InsertInfo("Bootup finished!");
//-----------------------------MAINLOOP------------------------------//
myLogger.InsertInfo("Enable Syncs and PDOs!");
CanHelper::instance()->EnableCanSync(can_sync_time_us);
System::StartTimer(10*timeout_rt_task_mainloop_ms);
myLogger.InsertInfo("Enable Syncs, PDOs and Timer!");
CANSyncHandler::instance()->StartCanSync();
TimerHandler::instance()->StartTimer(10*timeout_rt_task_mainloop_ms);
myLogger.InsertInfo("Entering main-loop!");
myLogger.InsertInfo("Waiting for emros-ros with IP: ", ip_ros_pc);
myLogger.InsertInfo("Waiting for emros-ros with IP: ", ip_ros_pc); //TODO: This should be moved into EtherHandler
while (1) {
// wait until high prio message is available
System::WaitForMsg(timeout_rt_task_mainloop_ms);
//handle high prio messages
while (System::GetHighPrioMsg(msg) != 0) {
if (System::IsTimerMsg(msg)) {
System::PostUserMsg(TASK_ID_USER, MSG_GRAPHICS_RT_OUTPUT,
MSG_PRIORITY_HIGH);
MSG_PRIORITY_HIGH); //TODO: This should be handled via TimerHandler
}
SdoHandler::instance()->CheckAndHandleNewSdo(msg);
CANSyncHandler::instance()->CheckAndHandleNewSync(msg);
basecontroller.CheckButton(msg); //TODO: This should run in a "Button-Handler"
robotstatecontroller.CheckButton(msg); //TODO: This should run in a "Button-Handler"
TimerHandler::instance()->CheckAndHandleNewTimerEvent(msg);
}
basecontroller.CyclicProcess(); //TODO: This should run in a "Timer-Handler"
// handle low prio message(s) afterwards
if (System::GetLowPrioMsg(msg) != 0) {
EthHandler::instance()->CheckAndHandleNewMsg(msg);
}
basecontroller.CyclicProcess(); //TODO: This should run in a "Timer-Handler"
}
}
......
......@@ -3,11 +3,11 @@
#include "../../emros_common/include/emros_common/wheel_drive_config.h"
#ifdef DEF_4WD
#include "can_mapping_4WD.h"
#include "pdo_mapping_4WD.h"
#elif defined DEF_2WD
#include "can_mapping_2WD.h"
#include "pdo_mapping_2WD.h"
#elif defined DEF_2WD_PLUS_AUX
#include "can_mapping_2WD_plus_auxiliary.h"
#include "pdo_mapping_2WD_plus_auxiliary.h"
#endif
#include "../../system/inc/factories.h"
#include <vector>
......@@ -29,13 +29,6 @@
#define FAULT_REACTION_ACTIVE 0x000F
#define FAULT 0x0008
class Test
{
public:
void bla();
};
class CanHelper final: public Singleton<CanHelper>
{
friend class Singleton<CanHelper> ;
......@@ -74,28 +67,27 @@ public:
Error AppEnableCsvMode(void);
Error AppDisableCsvMode(void);
Error AppProcessCsvMode(void);
Error SetCanOpenNodeBootedEvent(os_msg_t);
Error EnableCanSync(uint16_t sync_time);
private:
Error callculateNextControlWordToSwitchUpCia402Statemachine(uint16_t statusword, uint16_t &ctrlword);
int8_t *mMode_of_operation_display;
std::vector<Motor*>* mMotors;
std::vector<MotorPdoMapping*>* mMotors;
uint8_t mBootupSequence[127];
uint8_t mBootupSequenceLen;
uint8_t mBootupSequenceReadIdx;
bool mAppCsvModeEnabled;
bool mPowerEnabled;
bool mAppAutosetupModeEnabled;
bool mInitialized;
protected:
CanHelper() :
mAppCsvModeEnabled(false), mAppAutosetupModeEnabled(false), mBootupSequence(), mBootupSequenceLen(0), mBootupSequenceReadIdx(
mPowerEnabled(false), mAppAutosetupModeEnabled(false), mBootupSequence(), mBootupSequenceLen(0), mBootupSequenceReadIdx(
0), mMotors(nullptr), mMode_of_operation_display(nullptr), mInitialized(false)
{
......
#pragma once
#include "../../../nanotec/inc/nanoj.h"
#include <map>
#include <cstring>
#include "../../utility_ofc/include/utility_ofc/singleton.h"
#include "can_network_variables.h"
class Motor
{
public:
//types
typedef int8_t mode_of_operation_display_t;
typedef int32_t velocity_actual_value_t;
typedef int32_t position_actual_value_t;
typedef uint16_t status_word_t;
typedef int8_t mode_of_operation_t;
typedef int32_t target_velocity_t;
typedef int32_t target_position_t;
typedef uint16_t control_word_t;
virtual ~Motor()
{
}
void getModeOfOperationDisplay(mode_of_operation_display_t& value)
{
this->mode_of_operation_display.read(value);
}
void getVelocityActualValue(velocity_actual_value_t& value)
{
this->velocity_actual_value.read(value);
}
void getPositionActualVelocity(position_actual_value_t& value)
{
this->position_actual_value.read(value);
}
void getStatusWord(status_word_t& value)
{
this->status_word.read(value);
}
void getModeOfOperation(mode_of_operation_t& value)
{
this->mode_of_operation.read(value);
}
void getTargetVelocity(target_velocity_t& value)
{
this->target_velocity.read(value);
}
void getTargetPosition(target_position_t& value)
{
this->target_velocity.read(value);
}
void getControlWord(control_word_t& value)
{
this->control_word.read(value);
}
void setModeOfOperation(mode_of_operation_t value)
{
this->mode_of_operation.write(value);
}
void setTargetVelocity(target_velocity_t value)
{
this->target_velocity.write(value);
}
void setTargetPosition(target_position_t value)
{
this->target_velocity.write(value);
}
void setControlWord(control_word_t value)
{
this->control_word.write(value);
}
protected:
Motor()
{
}
CanRxNetworkVariable<mode_of_operation_display_t> mode_of_operation_display;
CanRxNetworkVariable<velocity_actual_value_t> velocity_actual_value;
CanRxNetworkVariable<position_actual_value_t> position_actual_value;
CanRxNetworkVariable<status_word_t> status_word;
CanTxNetworkVariable<mode_of_operation_t> mode_of_operation;
CanTxNetworkVariable<target_velocity_t> target_velocity;
CanTxNetworkVariable<target_position_t> target_position;
CanTxNetworkVariable<control_word_t> control_word;
private:
};
struct cmp_str
{
bool operator()(char const *a, char const *b)
{
return std::strcmp(a, b) < 0;
}
};
class MotorManager
{
public:
virtual ~MotorManager()
{
}
Motor* getMotor(const char* value)
{
Motor* m {this->mMotors[value]};
return (m);
}
protected:
MotorManager()
{
}
std::map<const char*, Motor*,cmp_str> mMotors;
};
class MotorRight : public Motor
{
public:
MotorRight()
{
this->mode_of_operation_display.updateConfig(0xA000,2);
this->velocity_actual_value.updateConfig(0xA1C0,3);
this->position_actual_value.updateConfig(0xA1C0,4);
this->status_word.updateConfig(0xA100,2);
this->mode_of_operation.updateConfig(0xA480,2);
this->target_velocity.updateConfig(0xA640,2);
this->control_word.updateConfig(0xA580,2);
}
};
class MotorLeft : public Motor
{
public:
MotorLeft()
{
this->mode_of_operation_display.updateConfig(0xA000,1);
this->velocity_actual_value.updateConfig(0xA1C0,1);
this->position_actual_value.updateConfig(0xA1C0,2);
this->status_word.updateConfig(0xA100,1);
this->mode_of_operation.updateConfig(0xA480,1);
this->target_velocity.updateConfig(0xA640,1);
this->control_word.updateConfig(0xA580,1);
}
};
class MotorManagerWD final: public MotorManager, public Singleton<MotorManagerWD>
{
friend class Singleton<MotorManagerWD>;
public:
~MotorManagerWD()
{
}
private:
MotorRight mMotorRight;
MotorLeft mMotorLeft;
protected:
MotorManagerWD()
{
this->mMotors["MotorRight"] = &mMotorRight;
this->mMotors["MotorLeft"] = &mMotorLeft;
}
};
#pragma once
#include "../../../nanotec/inc/nanoj.h"
#include <map>
#include <cstring>
#include "../../utility_ofc/include/utility_ofc/singleton.h"
#include "can_network_variables.h"
class Motor
{
public:
//types
typedef int8_t mode_of_operation_display_t;
typedef int32_t velocity_actual_value_t;
typedef int32_t position_actual_value_t;
typedef uint16_t status_word_t;
typedef int8_t mode_of_operation_t;
typedef int32_t target_velocity_t;
typedef int32_t target_position_t;
typedef uint16_t control_word_t;
virtual ~Motor()
{
}
void getModeOfOperationDisplay(mode_of_operation_display_t& value)
{
this->mode_of_operation_display.read(value);
}
void getVelocityActualValue(velocity_actual_value_t& value)
{
this->velocity_actual_value.read(value);
}
void getPositionActualVelocity(position_actual_value_t& value)
{
this->position_actual_value.read(value);
}
void getStatusWord(status_word_t& value)
{
this->status_word.read(value);
}
void getModeOfOperation(mode_of_operation_t& value)
{
this->mode_of_operation.read(value);
}
void getTargetVelocity(target_velocity_t& value)
{
this->target_velocity.read(value);
}
void getTargetPosition(target_position_t& value)
{
this->target_velocity.read(value);
}
void getControlWord(control_word_t& value)
{
this->control_word.read(value);
}
void setModeOfOperation(mode_of_operation_t value)
{
this->mode_of_operation.write(value);
}
void setTargetVelocity(target_velocity_t value)
{
this->target_velocity.write(value);
}
void setTargetPosition(target_position_t value)
{
this->target_velocity.write(value);
}
void setControlWord(control_word_t value)
{
this->control_word.write(value);
}
protected:
Motor()
{
}
CanRxNetworkVariable<mode_of_operation_display_t> mode_of_operation_display;
CanRxNetworkVariable<velocity_actual_value_t> velocity_actual_value;
CanRxNetworkVariable<position_actual_value_t> position_actual_value;
CanRxNetworkVariable<status_word_t> status_word;
CanTxNetworkVariable<mode_of_operation_t> mode_of_operation;
CanTxNetworkVariable<target_velocity_t> target_velocity;
CanTxNetworkVariable<target_position_t> target_position;
CanTxNetworkVariable<control_word_t> control_word;
private:
};
struct cmp_str
{
bool operator()(char const *a, char const *b)
{
return std::strcmp(a, b) < 0;
}
};
class MotorManager
{
public:
virtual ~MotorManager()
{
}
Motor* getMotor(const char* value)
{
Motor* m {this->mMotors[value]};
return (m);
}
protected:
MotorManager()
{
}
std::map<const char*, Motor*,cmp_str> mMotors;
};
class MotorRight : public Motor
{
public:
MotorRight()
{
this->mode_of_operation_display.updateConfig(0xA000,2);
this->velocity_actual_value.updateConfig(0xA1C0,3);
this->position_actual_value.updateConfig(0xA1C0,4);
this->status_word.updateConfig(0xA100,2);
this->mode_of_operation.updateConfig(0xA480,2);
this->target_velocity.updateConfig(0xA640,2);
this->control_word.updateConfig(0xA580,2);
}
};
class MotorLeft : public Motor
{
public:
MotorLeft()
{
this->mode_of_operation_display.updateConfig(0xA000,1);
this->velocity_actual_value.updateConfig(0xA1C0,1);
this->position_actual_value.updateConfig(0xA1C0,2);
this->status_word.updateConfig(0xA100,1);
this->mode_of_operation.updateConfig(0xA480,1);
this->target_velocity.updateConfig(0xA640,1);
this->control_word.updateConfig(0xA580,1);
}
};
class MotorAuxiliary : public Motor
{
public:
MotorAuxiliary()
{
this->mode_of_operation_display.updateConfig(0xA000,3);
this->velocity_actual_value.updateConfig(0xA1C0,5);
this->position_actual_value.updateConfig(0xA1C0,6);
this->status_word.updateConfig(0xA100,3);
this->mode_of_operation.updateConfig(0xA480,3);
this->target_velocity.updateConfig(0xA640,3);
this->control_word.updateConfig(0xA580,3);
}
};
class MotorManagerWD final: public MotorManager, public Singleton<MotorManagerWD>
{
friend class Singleton<MotorManagerWD>;
public:
~MotorManagerWD()
{
}
private:
MotorRight mMotorRight;
MotorLeft mMotorLeft;
MotorAuxiliary mMotorAuxiliary;
protected:
MotorManagerWD()
{
this->mMotors["MotorRight"] = &mMotorRight;
this->mMotors["MotorLeft"] = &mMotorLeft;
this->mMotors["MotorAuxiliary"] = &mMotorAuxiliary;
}
};
/*
*This Code is generated by the DCF-Generator. Don't modify it.
*
*
*(C) Nanotec
*
*/
#pragma once
#include "../../../nanotec/inc/nanoj.h"
#include <map>
#include <cstring>
#include "../../utility_ofc/include/utility_ofc/singleton.h"
#include "can_network_variables.h"
class Motor
{
public:
//types
typedef int8_t mode_of_operation_display_t;
typedef int32_t velocity_actual_value_t;
typedef int32_t position_actual_value_t;
typedef uint16_t status_word_t;
typedef int8_t mode_of_operation_t;
typedef int32_t target_velocity_t;
typedef int32_t target_position_t;
typedef uint16_t control_word_t;
virtual ~Motor()
{
}
void getModeOfOperationDisplay(mode_of_operation_display_t& value)
{
this->mode_of_operation_display.read(value);
}
void getVelocityActualValue(velocity_actual_value_t& value)
{
this->velocity_actual_value.read(value);
}
void getPositionActualVelocity(position_actual_value_t& value)
{
this->position_actual_value.read(value);
}
void getStatusWord(status_word_t& value)
{
this->status_word.read(value);
}
void getModeOfOperation(mode_of_operation_t& value)
{
this->mode_of_operation.read(value);
}
void getTargetVelocity(target_velocity_t& value)
{
this->target_velocity.read(value);
}
void getTargetPosition(target_position_t& value)
{
this->target_velocity.read(value);
}
void getControlWord(control_word_t& value)
{
this->control_word.read(value);
}
void setModeOfOperation(mode_of_operation_t value)
{
this->mode_of_operation.write(value);
}
void setTargetVelocity(target_velocity_t value)
{
this->target_velocity.write(value);
}
void setTargetPosition(target_position_t value)
{
this->target_velocity.write(value);
}
void setControlWord(control_word_t value)
{
this->control_word.write(value);
}
protected:
Motor()
{
}
CanRxNetworkVariable<mode_of_operation_display_t> mode_of_operation_display;
CanRxNetworkVariable<velocity_actual_value_t> velocity_actual_value;
CanRxNetworkVariable<position_actual_value_t> position_actual_value;
CanRxNetworkVariable<status_word_t> status_word;
CanTxNetworkVariable<mode_of_operation_t> mode_of_operation;
CanTxNetworkVariable<target_velocity_t> target_velocity;
CanTxNetworkVariable<target_position_t> target_position;
CanTxNetworkVariable<control_word_t> control_word;
private:
};
struct cmp_str
{
bool operator()(char const *a, char const *b)
{
return std::strcmp(a, b) < 0;
}
};
class MotorManager
{
public:
virtual ~MotorManager(){}
Motor* getMotor(const char* value)
{
return (this->mMotors[value]);
}
protected:
MotorManager(){}
std::map<const char*, Motor*,cmp_str> mMotors;
};
class MotorFrontLeft : public Motor
{
public:
MotorFrontLeft():velocity_demand(0xA0C0,1)
{
this->mode_of_operation_display.updateConfig(0xA000,1);
this->velocity_actual_value.updateConfig(0xA1C0,1);
this->position_actual_value.updateConfig(0xA1C0,2);
this->status_word.updateConfig(0xA100,1);
this->mode_of_operation.updateConfig(0xA480,1);
this->target_velocity.updateConfig(0xA640,1);
this->control_word.updateConfig(0xA580,1);
}
typedef int16_t velocity_demand_t;
CanRxNetworkVariable <velocity_demand_t> velocity_demand;
};
class MotorRearRight : public Motor
{
public:
MotorRearRight():velocity(0xA540,3)
{
this->mode_of_operation_display.updateConfig(0xA000,4);
this->velocity_actual_value.updateConfig(0xA1C0,7);
this->position_actual_value.updateConfig(0xA1C0,8);
this->status_word.updateConfig(0xA100,4);
this->mode_of_operation.updateConfig(0xA480,4);
this->target_velocity.updateConfig(0xA640,4);
this->control_word.updateConfig(0xA580,4);
}
typedef int16_t velocity_t;
CanTxNetworkVariable <velocity_t> velocity;
};
class MotorFrontRight : public Motor
{
public:
MotorFrontRight():velocity(0xA540,1)
{
this->mode_of_operation_display.updateConfig(0xA000,2);
this->velocity_actual_value.updateConfig(0xA1C0,3);
this->position_actual_value.updateConfig(0xA1C0,4);
this->status_word.updateConfig(0xA100,2);
this->mode_of_operation.updateConfig(0xA480,2);
this->target_velocity.updateConfig(0xA640,2);
this->control_word.updateConfig(0xA580,2);
}
typedef int16_t velocity_t;
CanTxNetworkVariable <velocity_t> velocity;
};
class MotorRearLeft : public Motor
{
public:
MotorRearLeft():velocity(0xA540,2)
{
this->mode_of_operation_display.updateConfig(0xA000,3);
this->velocity_actual_value.updateConfig(0xA1C0,5);
this->position_actual_value.updateConfig(0xA1C0,6);
this->status_word.updateConfig(0xA100,3);
this->mode_of_operation.updateConfig(0xA480,3);
this->target_velocity.updateConfig(0xA640,3);
this->control_word.updateConfig(0xA580,3);
}
typedef int16_t velocity_t;
CanTxNetworkVariable <velocity_t> velocity;
};
class MotorManagerWD : public MotorManager, public Singleton<MotorManagerWD>
{
friend class Singleton<MotorManagerWD>;
public:
~MotorManagerWD()
{
}
private:
MotorFrontLeft mMotorFrontLeft;
MotorRearRight mMotorRearRight;
MotorFrontRight mMotorFrontRight;
MotorRearLeft mMotorRearLeft;
protected:
MotorManagerWD()
{
this->mMotors["MotorFrontLeft"] = &mMotorFrontLeft;
this->mMotors["MotorRearRight"] = &mMotorRearRight;
this->mMotors["MotorFrontRight"] = &mMotorFrontRight;
this->mMotors["MotorRearLeft"] = &mMotorRearLeft;
}
};
......@@ -42,7 +42,7 @@ template<typename T>
return ((this->getInitialized())? Can::ReadNetworkVariable(getIndex(), getSubindex(), static_cast<void*>(&value)) : false);
}
void updateConfig(uint16_t index, uint8_t subindex)
void updateMapping(uint16_t index, uint8_t subindex)
{
this->mIndex = index;
this->mSubindex = subindex;
......
This diff is collapsed.
#include "motor.h"
struct cmp_str {
bool operator()(char const *a, char const *b) {
return std::strcmp(a, b) < 0;
}
};
class MotorManager {
public:
virtual ~MotorManager() {
}
Motor* getMotor(const char* value) {
Motor* m { this->mMotors[value] };
return (m);
}
protected:
MotorManager() {
}
std::map<const char*, Motor*, cmp_str> mMotors;
};
#pragma once
namespace modes_of_operation_specific {
typedef int8_t type; //Type of objects 6060h (mode of operation), 6061h (M
namespace code {
const type AutoSetup = -2;
const type ClockDirection = -1;
const type NoMode = 0;
const type ProfilePosition = 1;
const type Velocity = 2;
const type ProfileVelocity = 3;
const type ProfileTorque = 4;
const type Reserved = 5;
const type HomingMode = 6;
const type InterpolatedPosition = 7;
const type CyclicSynchronousSynchronousSynchronousPosition = 8;
const type CyclicSynchronousVelocity = 9;
const type CyclicSynchronousTorque = 10;
}
}
#pragma once
#include "pdo_mapping_motors.h"
class MotorRight : public MotorPdoMapping
{
public:
MotorRight()
{
this->mode_of_operation_display.updateMapping(0xA000,2);
this->velocity_actual_value.updateMapping(0xA1C0,3);
this->position_actual_value.updateMapping(0xA1C0,4);
this->status_word.updateMapping(0xA100,2);
this->mode_of_operation.updateMapping(0xA480,2);
this->target_velocity.updateMapping(0xA640,2);
this->control_word.updateMapping(0xA580,2);
}
};
class MotorLeft : public MotorPdoMapping
{
public:
MotorLeft()
{
this->mode_of_operation_display.updateMapping(0xA000,1);
this->velocity_actual_value.updateMapping(0xA1C0,1);
this->position_actual_value.updateMapping(0xA1C0,2);
this->status_word.updateMapping(0xA100,1);
this->mode_of_operation.updateMapping(0xA480,1);
this->target_velocity.updateMapping(0xA640,1);
this->control_word.updateMapping(0xA580,1);
}
};
class MotorManagerWD final: public MotorManager, public Singleton<MotorManagerWD>
{
friend class Singleton<MotorManagerWD>;
public:
~MotorManagerWD()
{
}
private:
MotorRight mMotorRight;
MotorLeft mMotorLeft;
protected:
MotorManagerWD()
{
this->mMotors["MotorRight"] = &mMotorRight;
this->mMotors["MotorLeft"] = &mMotorLeft;
}
};
#pragma once
#include "pdo_mapping_motors.h"
#include "motor_manager.h"
namespace{
MotorPdoMapping::node_id_t NodeIdLeftMotor =1;
MotorPdoMapping::node_id_t NodeIdRightMotor =2;
MotorPdoMapping::node_id_t NodeIdAuxiliaryMotor =3;