409 lines
14 KiB
C
409 lines
14 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <math.h>
|
|
|
|
#include "simdevice.h"
|
|
#include "serialdevice.h"
|
|
#include "serialadapter.h"
|
|
#include "hapticeffect.h"
|
|
#include "serial/arduino.h"
|
|
#include "serial/moza.h"
|
|
#include "serial/moza_new.h"
|
|
#include "serial/moza_ks_pro_wheel.h"
|
|
#include "../helper/parameters.h"
|
|
#include "../simulatorapi/simapi/simapi/simdata.h"
|
|
#include "../slog/slog.h"
|
|
|
|
#define KPHTOMPH .621317
|
|
|
|
int serial_wheel_update(SimDevice* this, SimData* simdata)
|
|
{
|
|
SerialDevice* serialdevice = (void *) this->derived;
|
|
|
|
switch (serialdevice->devicetype) {
|
|
case SIMDEVSUBTYPE_MOZA_NEW:
|
|
moza_new_update(serialdevice, simdata);
|
|
break;
|
|
|
|
case SERIALDEV__MOZA_KS_PRO_WHEEL:
|
|
moza_ks_pro_wheel_update(serialdevice, simdata);
|
|
break;
|
|
|
|
case SIMDEVSUBTYPE_MOZAR5:
|
|
default:
|
|
moza_update(serialdevice, simdata->rpms, simdata->maxrpm);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int serialdev_update(SimDevice* this, SimData* simdata)
|
|
{
|
|
SerialDevice* serialdevice = (void *) this->derived;
|
|
|
|
arduino_update(serialdevice, simdata, sizeof(SimData));
|
|
|
|
return 0;
|
|
}
|
|
|
|
int arduino_custom_updater(SimDevice* this, SimData* simdata)
|
|
{
|
|
SerialDevice* serialdevice = (void *) this->derived;
|
|
|
|
arduino_custom_update(serialdevice, simdata);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int arduino_customled_updater(SimDevice* this, SimData* simdata)
|
|
{
|
|
SerialDevice* serialdevice = (void *) this->derived;
|
|
|
|
arduino_customled_update(serialdevice, simdata);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int arduino_simled_updater(SimDevice* this, SimData* simdata)
|
|
{
|
|
SerialDevice* serialdevice = (void *) this->derived;
|
|
|
|
arduino_simled_update(serialdevice, simdata);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int arduino_shiftlights_update(SimDevice* this, SimData* simdata)
|
|
{
|
|
SerialDevice* serialdevice = (void *) this->derived;
|
|
int result = 1;
|
|
|
|
|
|
int num_avail_leds = serialdevice->numlights;
|
|
int rpm = simdata->rpms;
|
|
int maxrpm = simdata->maxrpm;
|
|
int litleds = 0;
|
|
if(rpm > 0 && maxrpm > 0)
|
|
{
|
|
int rpmmargin = ceil(.05*maxrpm);
|
|
int rpminterval = (maxrpm-rpmmargin) / (num_avail_leds);
|
|
|
|
|
|
for (int l = 1; l <= (num_avail_leds); l++)
|
|
{
|
|
if(rpm >= (rpminterval * l))
|
|
{
|
|
litleds = l;
|
|
}
|
|
}
|
|
}
|
|
|
|
serialdevice->u.shiftlightsdata.litleds = litleds;
|
|
//serialdevice->u.shiftlightsdata.rpm = simdata->rpms;
|
|
slogt("Updating arduino device lights to %i", serialdevice->u.shiftlightsdata.litleds);
|
|
// we can add configs to set all the colors
|
|
// i can move the size to the initialization since it should not change
|
|
size_t size = sizeof(ShiftLightsData);
|
|
|
|
arduino_update(serialdevice, &serialdevice->u.shiftlightsdata, size);
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
int arduino_simwind_update(SimDevice* this, SimData* simdata)
|
|
{
|
|
SerialDevice* serialdevice = (void *) this->derived;
|
|
int result = 1;
|
|
|
|
// sending over as mph, when you consider 255mph to be a reasonable upper limit
|
|
serialdevice->u.simwinddata.velocity = ceil(simdata->velocity*KPHTOMPH);
|
|
|
|
slogt("Updating arduino device speed to %i", serialdevice->u.simwinddata.velocity);
|
|
|
|
serialdevice->u.simwinddata.fanpower = (int)(serialdevice->fanpower * 255);
|
|
slogt("Sending fanpower: %i (from config: %f)", serialdevice->u.simwinddata.fanpower, serialdevice->fanpower);
|
|
size_t size = sizeof(SimWindData);
|
|
|
|
arduino_update(serialdevice, &serialdevice->u.simwinddata, size);
|
|
|
|
return result;
|
|
}
|
|
|
|
int arduino_simhaptic_update(SimDevice* this, SimData* simdata)
|
|
{
|
|
SerialDevice* serialdevice = (void *) this->derived;
|
|
|
|
int result = 1;
|
|
|
|
slogt("arduino haptic device updating");
|
|
|
|
double play = slipeffect(simdata, this->hapticeffect.effecttype, this->hapticeffect.tyre, this->hapticeffect.threshold, this->hapticeffect.useconfig, this->hapticeffect.configcheck, this->hapticeffect.tyrediameterconfig);
|
|
|
|
double rplay = play;
|
|
play = play * serialdevice->ampfactor;
|
|
if(play > 1.0)
|
|
{
|
|
play = 1.0;
|
|
}
|
|
int effectspeed = ceil(255 * play);
|
|
|
|
int motor = serialdevice->motorsposition;
|
|
|
|
if (play != serialdevice->state)
|
|
{
|
|
if (motor == 0 || motor == 4 || motor == 7 || motor == 8 || motor == 10 || motor == 11 || motor == 13 || motor == 14)
|
|
{
|
|
serialdevice->u.simhapticdata.effect1 = effectspeed;
|
|
serialdevice->u.simhapticdata.motor1 = 1;
|
|
slogt("Updating arduino haptic device with effect type %i speed motor speed %i on motor %i from original effect %f with ampfactor %f", this->hapticeffect.effecttype, serialdevice->u.simhapticdata.effect3, serialdevice->motorsposition, rplay, serialdevice->ampfactor);
|
|
}
|
|
if (motor == 2 || motor == 6 || motor == 8 || motor == 9 || motor == 10 || motor == 11 || motor == 12 || motor == 14)
|
|
{
|
|
serialdevice->u.simhapticdata.effect3 = effectspeed;
|
|
serialdevice->u.simhapticdata.motor3 = 1;
|
|
slogt("Updating arduino haptic device with effect type %i speed motor speed %i on motor %i from original effect %f with ampfactor %f", this->hapticeffect.effecttype, serialdevice->u.simhapticdata.effect3, serialdevice->motorsposition, rplay, serialdevice->ampfactor);
|
|
}
|
|
serialdevice->state = play;
|
|
}
|
|
|
|
size_t size = sizeof(SimHapticData);
|
|
|
|
arduino_update(serialdevice, &serialdevice->u.simhapticdata, size);
|
|
return result;
|
|
}
|
|
|
|
int serialdev_free(SimDevice* this)
|
|
{
|
|
SerialDevice* serialdevice = (void *) this->derived;
|
|
|
|
switch (serialdevice->devicetype) {
|
|
case (ARDUINODEV__HAPTIC):
|
|
|
|
serialdevice->u.simhapticdata.effect1 = 0;
|
|
serialdevice->u.simhapticdata.motor1 = 1;
|
|
serialdevice->u.simhapticdata.effect2 = 0;
|
|
serialdevice->u.simhapticdata.motor2 = 1;
|
|
serialdevice->u.simhapticdata.effect3 = 0;
|
|
serialdevice->u.simhapticdata.motor3 = 1;
|
|
serialdevice->u.simhapticdata.effect4 = 0;
|
|
serialdevice->u.simhapticdata.motor4 = 1;
|
|
serialdevice->state = 0;
|
|
|
|
size_t size = sizeof(SimHapticData);
|
|
monocoque_serial_write_block(serialdevice->id, &serialdevice->u.simhapticdata, size, 9000);
|
|
slogi("set zero to arduino device");
|
|
break;
|
|
case ARDUINODEV__SIMLED__CUSTOM:
|
|
//arduino_customled_free(serialdevice, true);
|
|
free(serialdevice->m.device_specific_config_file);
|
|
break;
|
|
case ARDUINODEV__SIMLED:
|
|
arduino_customled_free(serialdevice, false);
|
|
break;
|
|
}
|
|
|
|
|
|
monocoque_serial_free(serialdevice);
|
|
|
|
free(serialdevice);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int serial_wheel_free(SimDevice* this)
|
|
{
|
|
SerialDevice* serialdevice = (void *) this->derived;
|
|
|
|
monocoque_serial_free(serialdevice);
|
|
|
|
free(serialdevice);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int serialdev_init(SerialDevice* serialdevice, DeviceSettings* ds, SimInfo* siminfo)
|
|
{
|
|
slogi("initializing serial device on port %s to %i...", ds->serialdevsettings.portdev, ds->serialdevsettings.baud);
|
|
int error = 0;
|
|
|
|
|
|
serialdevice->motorsposition = ds->serialdevsettings.motorsposition;
|
|
serialdevice->baudrate = ds->serialdevsettings.baud;
|
|
|
|
switch (serialdevice->devicetype)
|
|
{
|
|
case SERIALDEV__MOZAR5:
|
|
// the wheel stuff assumed it was a usb
|
|
//error = wheeldev_init(&serialdevice->u.wheeldevice, ds);
|
|
// maybe this call a more generic serial wheel init first
|
|
error = moza_init(serialdevice, ds->serialdevsettings.portdev);
|
|
break;
|
|
case SERIALDEV__MOZA_NEW:
|
|
error = moza_new_init(serialdevice, ds->serialdevsettings.portdev);
|
|
break;
|
|
case SERIALDEV__MOZA_KS_PRO_WHEEL:
|
|
error = moza_ks_pro_wheel_init(serialdevice, ds->serialdevsettings.portdev);
|
|
break;
|
|
case ARDUINODEV__SIMLED__CUSTOM:
|
|
serialdevice->m.device_specific_config_file = strdup(ds->specific_config_file);
|
|
error = arduino_custom_init(serialdevice, ds->serialdevsettings.portdev, serialdevice->m.device_specific_config_file, true);
|
|
if(error < 0)
|
|
{
|
|
free(serialdevice->m.device_specific_config_file);
|
|
}
|
|
break;
|
|
case ARDUINODEV__CUSTOM:
|
|
serialdevice->m.device_specific_config_file = strdup(ds->specific_config_file);
|
|
error = arduino_custom_init(serialdevice, ds->serialdevsettings.portdev, serialdevice->m.device_specific_config_file, false);
|
|
if(error < 0)
|
|
{
|
|
free(serialdevice->m.device_specific_config_file);
|
|
}
|
|
break;
|
|
case ARDUINODEV__SIMLED:
|
|
error = arduino_custom_init(serialdevice, ds->serialdevsettings.portdev, NULL, false);
|
|
break;
|
|
default:
|
|
error = arduino_init(serialdevice, ds->serialdevsettings.portdev);
|
|
break;
|
|
}
|
|
|
|
|
|
return error;
|
|
}
|
|
|
|
static const vtable serial_simdevice_vtable = { &serialdev_update, &serialdev_free };
|
|
static const vtable arduino_shiftlights_vtable = { &arduino_shiftlights_update, &serialdev_free };
|
|
static const vtable arduino_simled_vtable = { &arduino_simled_updater, &serialdev_free };
|
|
static const vtable arduino_custom_vtable = { &arduino_custom_updater, &serialdev_free };
|
|
static const vtable arduino_simled_custom_vtable = { &arduino_customled_updater, &serialdev_free };
|
|
static const vtable arduino_simwind_vtable = { &arduino_simwind_update, &serialdev_free };
|
|
static const vtable arduino_simhaptic_vtable = { &arduino_simhaptic_update, &serialdev_free };
|
|
static const vtable serialwheel_vtable = { &serial_wheel_update, &serial_wheel_free };
|
|
|
|
SerialDevice* new_serial_device(DeviceSettings* ds, MonocoqueSettings* ms, SimInfo* siminfo) {
|
|
|
|
SerialDevice* this = (SerialDevice*) malloc(sizeof(SerialDevice));
|
|
|
|
this->m.update = &update;
|
|
this->m.free = &simdevfree;
|
|
this->m.derived = this;
|
|
this->m.vtable = &serial_simdevice_vtable;
|
|
this->type = SERIALDEV_ARDUINO;
|
|
int error = 0;
|
|
|
|
slogt("Attempting to configure arduino device with subtype: %i", ds->dev_subtype);
|
|
switch (ds->dev_subtype) {
|
|
case (SIMDEVTYPE_SHIFTLIGHTS):
|
|
this->devicetype = ARDUINODEV__SHIFTLIGHTS;
|
|
this->numlights = ds->serialdevsettings.numlights;
|
|
this->m.vtable = &arduino_shiftlights_vtable;
|
|
slogi("Initializing arduino device for shiftlights.");
|
|
break;
|
|
case (SIMDEVTYPE_SIMLED):
|
|
|
|
if(ds->has_config == true)
|
|
{
|
|
this->devicetype = ARDUINODEV__SIMLED__CUSTOM;
|
|
this->startled = ds->serialdevsettings.startled;
|
|
this->endled = ds->serialdevsettings.endled;
|
|
this->m.vtable = &arduino_simled_custom_vtable;
|
|
slogi("Initializing arduino device for custom simled.");
|
|
}
|
|
else
|
|
{
|
|
this->devicetype = ARDUINODEV__SIMLED;
|
|
this->numleds = ds->serialdevsettings.numleds;
|
|
this->startled = ds->serialdevsettings.startled;
|
|
this->endled = ds->serialdevsettings.endled;
|
|
this->m.vtable = &arduino_simled_vtable;
|
|
slogi("Initializing arduino device for simled.");
|
|
}
|
|
break;
|
|
case (SIMDEVTYPE_SIMWIND):
|
|
this->devicetype = ARDUINODEV__SIMWIND;
|
|
this->m.vtable = &arduino_simwind_vtable;
|
|
this->fanpower = ds->serialdevsettings.fanpower;
|
|
slogi("Initializing arduino devices for sim wind with fanpower: %f", this->fanpower);
|
|
break;
|
|
case (SIMDEVTYPE_ARDUINOCUSTOM):
|
|
this->devicetype = ARDUINODEV__CUSTOM;
|
|
this->m.vtable = &arduino_custom_vtable;
|
|
slogi("Initializing custom arduino device.");
|
|
break;
|
|
case (SIMDEVTYPE_SERIALHAPTIC):
|
|
if(siminfo->SimSupportsHapticEffects == false)
|
|
{
|
|
error = MONOCOQUE_ERROR_UNSUPPORTED_SIM_FEATURE;
|
|
}
|
|
this->devicetype = ARDUINODEV__HAPTIC;
|
|
this->m.vtable = &arduino_simhaptic_vtable;
|
|
this->u.simhapticdata.motor1 = 0;
|
|
this->u.simhapticdata.motor2 = 0;
|
|
this->u.simhapticdata.motor3 = 0;
|
|
this->u.simhapticdata.motor4 = 0;
|
|
this->u.simhapticdata.effect1 = 0;
|
|
this->u.simhapticdata.effect2 = 0;
|
|
this->u.simhapticdata.effect3 = 0;
|
|
this->u.simhapticdata.effect4 = 0;
|
|
this->state = 0;
|
|
this->ampfactor = ds->serialdevsettings.ampfactor;
|
|
this->fanpower = ds->serialdevsettings.fanpower;
|
|
slogi("Initializing arduino device for haptic effects.");
|
|
break;
|
|
case (SIMDEVTYPE_SERIALWHEEL):
|
|
this->type = SERIALDEV_WHEEL;
|
|
|
|
switch (ds->dev_subsubtype) {
|
|
|
|
case SIMDEVSUBTYPE_MOZA_NEW:
|
|
slogi("Initializing new firmware Moza serial wheel device.");
|
|
this->devicetype = SERIALDEV__MOZA_NEW;
|
|
this->m.vtable = &serialwheel_vtable;
|
|
break;
|
|
case SIMDEVSUBTYPE_MOZA_KS_PRO_WHEEL:
|
|
slogi("Initializing new firmware Moza serial wheel device.");
|
|
this->devicetype = SERIALDEV__MOZA_KS_PRO_WHEEL;
|
|
this->m.vtable = &serialwheel_vtable;
|
|
break;
|
|
case SIMDEVSUBTYPE_MOZAR5:
|
|
default:
|
|
//move this stuff to wheeldevice or it's own serial wheel device module
|
|
slogi("Initializing Moza serial wheel device.");
|
|
this->devicetype = SERIALDEV__MOZAR5;
|
|
this->m.vtable = &serialwheel_vtable;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(this->devicetype == ARDUINODEV__HAPTIC && error == 0)
|
|
{
|
|
this->m.hapticeffect.threshold = ds->threshold;
|
|
this->m.hapticeffect.effecttype = ds->effect_type;
|
|
slogt("Haptic effect: %i %i", this->m.hapticeffect.effecttype, ds->effect_type);
|
|
this->m.hapticeffect.tyre = ds->tyre;
|
|
this->m.hapticeffect.useconfig = ms->useconfig;
|
|
this->m.hapticeffect.configcheck = &ms->configcheck;
|
|
this->m.hapticeffect.tyrediameterconfig = ms->tyre_diameter_config;
|
|
}
|
|
|
|
if(error == 0)
|
|
{
|
|
slogi("Starting serial device initialization");
|
|
error = serialdev_init(this, ds, siminfo);
|
|
}
|
|
|
|
if (error != 0)
|
|
{
|
|
slogw("Did not initialize usb device due to error code %i", error);
|
|
free(this);
|
|
return NULL;
|
|
}
|
|
|
|
return this;
|
|
}
|